blob: 6ff5ea1ae8f80e2b9ff9d37c47519fdf4834cd57 [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 Stoza71bded52016-10-19 11:10:33 -070026#include <gfx/FloatRect.h>
Dan Stoza651bf312015-10-23 17:03:17 -070027
28#include <ui/Fence.h>
29#include <ui/GraphicBuffer.h>
30#include <ui/Region.h>
31
32#include <android/configuration.h>
33
Dan Stoza09e7a272016-04-14 12:31:01 -070034#include <algorithm>
Dan Stoza651bf312015-10-23 17:03:17 -070035#include <inttypes.h>
36
37extern "C" {
38 static void hotplug_hook(hwc2_callback_data_t callbackData,
39 hwc2_display_t displayId, int32_t intConnected) {
40 auto device = static_cast<HWC2::Device*>(callbackData);
41 auto display = device->getDisplayById(displayId);
42 if (display) {
43 auto connected = static_cast<HWC2::Connection>(intConnected);
44 device->callHotplug(std::move(display), connected);
45 } else {
46 ALOGE("Hotplug callback called with unknown display %" PRIu64,
47 displayId);
48 }
49 }
50
51 static void refresh_hook(hwc2_callback_data_t callbackData,
52 hwc2_display_t displayId) {
53 auto device = static_cast<HWC2::Device*>(callbackData);
54 auto display = device->getDisplayById(displayId);
55 if (display) {
56 device->callRefresh(std::move(display));
57 } else {
58 ALOGE("Refresh callback called with unknown display %" PRIu64,
59 displayId);
60 }
61 }
62
63 static void vsync_hook(hwc2_callback_data_t callbackData,
64 hwc2_display_t displayId, int64_t timestamp) {
65 auto device = static_cast<HWC2::Device*>(callbackData);
66 auto display = device->getDisplayById(displayId);
67 if (display) {
68 device->callVsync(std::move(display), timestamp);
69 } else {
70 ALOGE("Vsync callback called with unknown display %" PRIu64,
71 displayId);
72 }
73 }
74}
75
76using android::Fence;
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;
Dan Stoza71bded52016-10-19 11:10:33 -070082using android::gfx::FloatRect;
Chia-I Wuaab99f52016-10-05 12:59:58 +080083using android::hardware::Return;
84using android::hardware::Void;
Dan Stoza651bf312015-10-23 17:03:17 -070085
86namespace HWC2 {
87
Chia-I Wuaab99f52016-10-05 12:59:58 +080088namespace Hwc2 = android::Hwc2;
89
Dan Stoza651bf312015-10-23 17:03:17 -070090// Device methods
91
Chia-I Wuaab99f52016-10-05 12:59:58 +080092#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -070093Device::Device(hwc2_device_t* device)
94 : mHwcDevice(device),
95 mCreateVirtualDisplay(nullptr),
96 mDestroyVirtualDisplay(nullptr),
97 mDump(nullptr),
98 mGetMaxVirtualDisplayCount(nullptr),
99 mRegisterCallback(nullptr),
100 mAcceptDisplayChanges(nullptr),
101 mCreateLayer(nullptr),
102 mDestroyLayer(nullptr),
103 mGetActiveConfig(nullptr),
104 mGetChangedCompositionTypes(nullptr),
Dan Stoza076ac672016-03-14 10:47:53 -0700105 mGetColorModes(nullptr),
Dan Stoza651bf312015-10-23 17:03:17 -0700106 mGetDisplayAttribute(nullptr),
107 mGetDisplayConfigs(nullptr),
108 mGetDisplayName(nullptr),
109 mGetDisplayRequests(nullptr),
110 mGetDisplayType(nullptr),
111 mGetDozeSupport(nullptr),
Dan Stoza7d7ae732016-03-16 12:23:40 -0700112 mGetHdrCapabilities(nullptr),
Dan Stoza651bf312015-10-23 17:03:17 -0700113 mGetReleaseFences(nullptr),
114 mPresentDisplay(nullptr),
115 mSetActiveConfig(nullptr),
116 mSetClientTarget(nullptr),
Dan Stoza076ac672016-03-14 10:47:53 -0700117 mSetColorMode(nullptr),
Dan Stoza5df2a862016-03-24 16:19:37 -0700118 mSetColorTransform(nullptr),
Dan Stoza651bf312015-10-23 17:03:17 -0700119 mSetOutputBuffer(nullptr),
120 mSetPowerMode(nullptr),
121 mSetVsyncEnabled(nullptr),
122 mValidateDisplay(nullptr),
123 mSetCursorPosition(nullptr),
124 mSetLayerBuffer(nullptr),
125 mSetLayerSurfaceDamage(nullptr),
126 mSetLayerBlendMode(nullptr),
127 mSetLayerColor(nullptr),
128 mSetLayerCompositionType(nullptr),
Dan Stoza5df2a862016-03-24 16:19:37 -0700129 mSetLayerDataspace(nullptr),
Dan Stoza651bf312015-10-23 17:03:17 -0700130 mSetLayerDisplayFrame(nullptr),
131 mSetLayerPlaneAlpha(nullptr),
132 mSetLayerSidebandStream(nullptr),
133 mSetLayerSourceCrop(nullptr),
134 mSetLayerTransform(nullptr),
135 mSetLayerVisibleRegion(nullptr),
136 mSetLayerZOrder(nullptr),
Chia-I Wuaab99f52016-10-05 12:59:58 +0800137#else
138Device::Device()
139 : mComposer(std::make_unique<Hwc2::Composer>()),
140#endif // BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700141 mCapabilities(),
142 mDisplays(),
143 mHotplug(),
144 mPendingHotplugs(),
145 mRefresh(),
146 mPendingRefreshes(),
147 mVsync(),
148 mPendingVsyncs()
149{
150 loadCapabilities();
151 loadFunctionPointers();
152 registerCallbacks();
153}
154
155Device::~Device()
156{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800157#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700158 if (mHwcDevice == nullptr) {
159 return;
160 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800161#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700162
163 for (auto element : mDisplays) {
Dan Stoza38628982016-07-13 15:48:58 -0700164 auto display = element.second.lock();
165 if (!display) {
166 ALOGE("~Device: Found a display (%" PRId64 " that has already been"
167 " destroyed", element.first);
168 continue;
169 }
Dan Stoza651bf312015-10-23 17:03:17 -0700170
171 DisplayType displayType = HWC2::DisplayType::Invalid;
172 auto error = display->getType(&displayType);
173 if (error != Error::None) {
174 ALOGE("~Device: Failed to determine type of display %" PRIu64
175 ": %s (%d)", display->getId(), to_string(error).c_str(),
176 static_cast<int32_t>(error));
177 continue;
178 }
179
180 if (displayType == HWC2::DisplayType::Physical) {
181 error = display->setVsyncEnabled(HWC2::Vsync::Disable);
182 if (error != Error::None) {
183 ALOGE("~Device: Failed to disable vsync for display %" PRIu64
184 ": %s (%d)", display->getId(), to_string(error).c_str(),
185 static_cast<int32_t>(error));
186 }
187 }
188 }
189
Chia-I Wuaab99f52016-10-05 12:59:58 +0800190#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700191 hwc2_close(mHwcDevice);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800192#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700193}
194
195// Required by HWC2 device
196
197std::string Device::dump() const
198{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800199#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700200 uint32_t numBytes = 0;
201 mDump(mHwcDevice, &numBytes, nullptr);
202
203 std::vector<char> buffer(numBytes);
204 mDump(mHwcDevice, &numBytes, buffer.data());
205
206 return std::string(buffer.data(), buffer.size());
Chia-I Wuaab99f52016-10-05 12:59:58 +0800207#else
208 return mComposer->dumpDebugInfo();
209#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700210}
211
212uint32_t Device::getMaxVirtualDisplayCount() const
213{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800214#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700215 return mGetMaxVirtualDisplayCount(mHwcDevice);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800216#else
217 return mComposer->getMaxVirtualDisplayCount();
218#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700219}
220
221Error Device::createVirtualDisplay(uint32_t width, uint32_t height,
Dan Stoza5cf424b2016-05-20 14:02:39 -0700222 android_pixel_format_t* format, std::shared_ptr<Display>* outDisplay)
Dan Stoza651bf312015-10-23 17:03:17 -0700223{
224 ALOGI("Creating virtual display");
225
226 hwc2_display_t displayId = 0;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800227#ifdef BYPASS_IHWC
Dan Stoza5cf424b2016-05-20 14:02:39 -0700228 int32_t intFormat = static_cast<int32_t>(*format);
Dan Stoza651bf312015-10-23 17:03:17 -0700229 int32_t intError = mCreateVirtualDisplay(mHwcDevice, width, height,
Dan Stoza5cf424b2016-05-20 14:02:39 -0700230 &intFormat, &displayId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800231#else
232 auto intFormat = static_cast<Hwc2::PixelFormat>(*format);
233 auto intError = mComposer->createVirtualDisplay(width, height,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800234 &intFormat, &displayId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800235#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700236 auto error = static_cast<Error>(intError);
237 if (error != Error::None) {
238 return error;
239 }
240
241 ALOGI("Created virtual display");
Dan Stoza5cf424b2016-05-20 14:02:39 -0700242 *format = static_cast<android_pixel_format_t>(intFormat);
Dan Stoza651bf312015-10-23 17:03:17 -0700243 *outDisplay = getDisplayById(displayId);
Dan Stoza38628982016-07-13 15:48:58 -0700244 if (!*outDisplay) {
245 ALOGE("Failed to get display by id");
246 return Error::BadDisplay;
247 }
Dan Stoza651bf312015-10-23 17:03:17 -0700248 (*outDisplay)->setVirtual();
249 return Error::None;
250}
251
252void Device::registerHotplugCallback(HotplugCallback hotplug)
253{
254 ALOGV("registerHotplugCallback");
255 mHotplug = hotplug;
256 for (auto& pending : mPendingHotplugs) {
257 auto& display = pending.first;
258 auto connected = pending.second;
259 ALOGV("Sending pending hotplug(%" PRIu64 ", %s)", display->getId(),
260 to_string(connected).c_str());
261 mHotplug(std::move(display), connected);
262 }
263}
264
265void Device::registerRefreshCallback(RefreshCallback refresh)
266{
267 mRefresh = refresh;
268 for (auto& pending : mPendingRefreshes) {
269 mRefresh(std::move(pending));
270 }
271}
272
273void Device::registerVsyncCallback(VsyncCallback vsync)
274{
275 mVsync = vsync;
276 for (auto& pending : mPendingVsyncs) {
277 auto& display = pending.first;
278 auto timestamp = pending.second;
279 mVsync(std::move(display), timestamp);
280 }
281}
282
283// For use by Device callbacks
284
285void Device::callHotplug(std::shared_ptr<Display> display, Connection connected)
286{
287 if (connected == Connection::Connected) {
288 if (!display->isConnected()) {
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800289#ifndef BYPASS_IHWC
290 mComposer->setClientTargetSlotCount(display->getId());
291#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700292 display->loadConfigs();
293 display->setConnected(true);
294 }
295 } else {
296 display->setConnected(false);
297 mDisplays.erase(display->getId());
298 }
299
300 if (mHotplug) {
301 mHotplug(std::move(display), connected);
302 } else {
303 ALOGV("callHotplug called, but no valid callback registered, storing");
304 mPendingHotplugs.emplace_back(std::move(display), connected);
305 }
306}
307
308void Device::callRefresh(std::shared_ptr<Display> display)
309{
310 if (mRefresh) {
311 mRefresh(std::move(display));
312 } else {
313 ALOGV("callRefresh called, but no valid callback registered, storing");
314 mPendingRefreshes.emplace_back(std::move(display));
315 }
316}
317
318void Device::callVsync(std::shared_ptr<Display> display, nsecs_t timestamp)
319{
320 if (mVsync) {
321 mVsync(std::move(display), timestamp);
322 } else {
323 ALOGV("callVsync called, but no valid callback registered, storing");
324 mPendingVsyncs.emplace_back(std::move(display), timestamp);
325 }
326}
327
328// Other Device methods
329
330std::shared_ptr<Display> Device::getDisplayById(hwc2_display_t id) {
331 if (mDisplays.count(id) != 0) {
Dan Stoza38628982016-07-13 15:48:58 -0700332 auto strongDisplay = mDisplays[id].lock();
333 ALOGE_IF(!strongDisplay, "Display %" PRId64 " is in mDisplays but is no"
334 " longer alive", id);
335 return strongDisplay;
Dan Stoza651bf312015-10-23 17:03:17 -0700336 }
337
338 auto display = std::make_shared<Display>(*this, id);
339 mDisplays.emplace(id, display);
340 return display;
341}
342
343// Device initialization methods
344
345void Device::loadCapabilities()
346{
347 static_assert(sizeof(Capability) == sizeof(int32_t),
348 "Capability size has changed");
Chia-I Wuaab99f52016-10-05 12:59:58 +0800349#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700350 uint32_t numCapabilities = 0;
351 mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, nullptr);
Dan Stoza9f26a9c2016-06-22 14:51:09 -0700352 std::vector<Capability> capabilities(numCapabilities);
353 auto asInt = reinterpret_cast<int32_t*>(capabilities.data());
Dan Stoza651bf312015-10-23 17:03:17 -0700354 mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, asInt);
Dan Stoza9f26a9c2016-06-22 14:51:09 -0700355 for (auto capability : capabilities) {
356 mCapabilities.emplace(capability);
357 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800358#else
359 auto capabilities = mComposer->getCapabilities();
360 for (auto capability : capabilities) {
361 mCapabilities.emplace(static_cast<Capability>(capability));
362 }
363#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700364}
365
Dan Stoza09e7a272016-04-14 12:31:01 -0700366bool Device::hasCapability(HWC2::Capability capability) const
367{
368 return std::find(mCapabilities.cbegin(), mCapabilities.cend(),
369 capability) != mCapabilities.cend();
370}
371
Dan Stoza651bf312015-10-23 17:03:17 -0700372void Device::loadFunctionPointers()
373{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800374#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700375 // For all of these early returns, we log an error message inside
376 // loadFunctionPointer specifying which function failed to load
377
378 // Display function pointers
Dan Stoza7d7ae732016-03-16 12:23:40 -0700379 if (!loadFunctionPointer(FunctionDescriptor::CreateVirtualDisplay,
Dan Stoza651bf312015-10-23 17:03:17 -0700380 mCreateVirtualDisplay)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700381 if (!loadFunctionPointer(FunctionDescriptor::DestroyVirtualDisplay,
Dan Stoza651bf312015-10-23 17:03:17 -0700382 mDestroyVirtualDisplay)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700383 if (!loadFunctionPointer(FunctionDescriptor::Dump, mDump)) return;
384 if (!loadFunctionPointer(FunctionDescriptor::GetMaxVirtualDisplayCount,
Dan Stoza651bf312015-10-23 17:03:17 -0700385 mGetMaxVirtualDisplayCount)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700386 if (!loadFunctionPointer(FunctionDescriptor::RegisterCallback,
Dan Stoza651bf312015-10-23 17:03:17 -0700387 mRegisterCallback)) return;
388
389 // Device function pointers
Dan Stoza7d7ae732016-03-16 12:23:40 -0700390 if (!loadFunctionPointer(FunctionDescriptor::AcceptDisplayChanges,
Dan Stoza651bf312015-10-23 17:03:17 -0700391 mAcceptDisplayChanges)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700392 if (!loadFunctionPointer(FunctionDescriptor::CreateLayer,
Dan Stoza651bf312015-10-23 17:03:17 -0700393 mCreateLayer)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700394 if (!loadFunctionPointer(FunctionDescriptor::DestroyLayer,
Dan Stoza651bf312015-10-23 17:03:17 -0700395 mDestroyLayer)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700396 if (!loadFunctionPointer(FunctionDescriptor::GetActiveConfig,
Dan Stoza651bf312015-10-23 17:03:17 -0700397 mGetActiveConfig)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700398 if (!loadFunctionPointer(FunctionDescriptor::GetChangedCompositionTypes,
Dan Stoza651bf312015-10-23 17:03:17 -0700399 mGetChangedCompositionTypes)) return;
Dan Stoza076ac672016-03-14 10:47:53 -0700400 if (!loadFunctionPointer(FunctionDescriptor::GetColorModes,
401 mGetColorModes)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700402 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayAttribute,
Dan Stoza651bf312015-10-23 17:03:17 -0700403 mGetDisplayAttribute)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700404 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayConfigs,
Dan Stoza651bf312015-10-23 17:03:17 -0700405 mGetDisplayConfigs)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700406 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayName,
Dan Stoza651bf312015-10-23 17:03:17 -0700407 mGetDisplayName)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700408 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayRequests,
Dan Stoza651bf312015-10-23 17:03:17 -0700409 mGetDisplayRequests)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700410 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayType,
Dan Stoza651bf312015-10-23 17:03:17 -0700411 mGetDisplayType)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700412 if (!loadFunctionPointer(FunctionDescriptor::GetDozeSupport,
Dan Stoza651bf312015-10-23 17:03:17 -0700413 mGetDozeSupport)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700414 if (!loadFunctionPointer(FunctionDescriptor::GetHdrCapabilities,
415 mGetHdrCapabilities)) return;
416 if (!loadFunctionPointer(FunctionDescriptor::GetReleaseFences,
Dan Stoza651bf312015-10-23 17:03:17 -0700417 mGetReleaseFences)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700418 if (!loadFunctionPointer(FunctionDescriptor::PresentDisplay,
Dan Stoza651bf312015-10-23 17:03:17 -0700419 mPresentDisplay)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700420 if (!loadFunctionPointer(FunctionDescriptor::SetActiveConfig,
Dan Stoza651bf312015-10-23 17:03:17 -0700421 mSetActiveConfig)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700422 if (!loadFunctionPointer(FunctionDescriptor::SetClientTarget,
Dan Stoza651bf312015-10-23 17:03:17 -0700423 mSetClientTarget)) return;
Dan Stoza076ac672016-03-14 10:47:53 -0700424 if (!loadFunctionPointer(FunctionDescriptor::SetColorMode,
425 mSetColorMode)) return;
Dan Stoza5df2a862016-03-24 16:19:37 -0700426 if (!loadFunctionPointer(FunctionDescriptor::SetColorTransform,
427 mSetColorTransform)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700428 if (!loadFunctionPointer(FunctionDescriptor::SetOutputBuffer,
Dan Stoza651bf312015-10-23 17:03:17 -0700429 mSetOutputBuffer)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700430 if (!loadFunctionPointer(FunctionDescriptor::SetPowerMode,
Dan Stoza651bf312015-10-23 17:03:17 -0700431 mSetPowerMode)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700432 if (!loadFunctionPointer(FunctionDescriptor::SetVsyncEnabled,
Dan Stoza651bf312015-10-23 17:03:17 -0700433 mSetVsyncEnabled)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700434 if (!loadFunctionPointer(FunctionDescriptor::ValidateDisplay,
Dan Stoza651bf312015-10-23 17:03:17 -0700435 mValidateDisplay)) return;
436
437 // Layer function pointers
Dan Stoza7d7ae732016-03-16 12:23:40 -0700438 if (!loadFunctionPointer(FunctionDescriptor::SetCursorPosition,
Dan Stoza651bf312015-10-23 17:03:17 -0700439 mSetCursorPosition)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700440 if (!loadFunctionPointer(FunctionDescriptor::SetLayerBuffer,
Dan Stoza651bf312015-10-23 17:03:17 -0700441 mSetLayerBuffer)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700442 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSurfaceDamage,
Dan Stoza651bf312015-10-23 17:03:17 -0700443 mSetLayerSurfaceDamage)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700444 if (!loadFunctionPointer(FunctionDescriptor::SetLayerBlendMode,
Dan Stoza651bf312015-10-23 17:03:17 -0700445 mSetLayerBlendMode)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700446 if (!loadFunctionPointer(FunctionDescriptor::SetLayerColor,
Dan Stoza651bf312015-10-23 17:03:17 -0700447 mSetLayerColor)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700448 if (!loadFunctionPointer(FunctionDescriptor::SetLayerCompositionType,
Dan Stoza651bf312015-10-23 17:03:17 -0700449 mSetLayerCompositionType)) return;
Dan Stoza5df2a862016-03-24 16:19:37 -0700450 if (!loadFunctionPointer(FunctionDescriptor::SetLayerDataspace,
451 mSetLayerDataspace)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700452 if (!loadFunctionPointer(FunctionDescriptor::SetLayerDisplayFrame,
Dan Stoza651bf312015-10-23 17:03:17 -0700453 mSetLayerDisplayFrame)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700454 if (!loadFunctionPointer(FunctionDescriptor::SetLayerPlaneAlpha,
Dan Stoza651bf312015-10-23 17:03:17 -0700455 mSetLayerPlaneAlpha)) return;
Dan Stoza09e7a272016-04-14 12:31:01 -0700456 if (hasCapability(Capability::SidebandStream)) {
457 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSidebandStream,
458 mSetLayerSidebandStream)) return;
459 }
Dan Stoza7d7ae732016-03-16 12:23:40 -0700460 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSourceCrop,
Dan Stoza651bf312015-10-23 17:03:17 -0700461 mSetLayerSourceCrop)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700462 if (!loadFunctionPointer(FunctionDescriptor::SetLayerTransform,
Dan Stoza651bf312015-10-23 17:03:17 -0700463 mSetLayerTransform)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700464 if (!loadFunctionPointer(FunctionDescriptor::SetLayerVisibleRegion,
Dan Stoza651bf312015-10-23 17:03:17 -0700465 mSetLayerVisibleRegion)) return;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700466 if (!loadFunctionPointer(FunctionDescriptor::SetLayerZOrder,
Dan Stoza651bf312015-10-23 17:03:17 -0700467 mSetLayerZOrder)) return;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800468#endif // BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700469}
470
Chia-I Wuaab99f52016-10-05 12:59:58 +0800471namespace {
472class ComposerCallback : public Hwc2::IComposerCallback {
473public:
474 ComposerCallback(Device* device) : mDevice(device) {}
475
476 Return<void> onHotplug(Hwc2::Display display,
477 Connection connected) override
478 {
479 hotplug_hook(mDevice, display, static_cast<int32_t>(connected));
480 return Void();
481 }
482
483 Return<void> onRefresh(Hwc2::Display display) override
484 {
485 refresh_hook(mDevice, display);
486 return Void();
487 }
488
489 Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override
490 {
491 vsync_hook(mDevice, display, timestamp);
492 return Void();
493 }
494
495private:
496 Device* mDevice;
497};
498} // namespace anonymous
499
Dan Stoza651bf312015-10-23 17:03:17 -0700500void Device::registerCallbacks()
501{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800502#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700503 registerCallback<HWC2_PFN_HOTPLUG>(Callback::Hotplug, hotplug_hook);
504 registerCallback<HWC2_PFN_REFRESH>(Callback::Refresh, refresh_hook);
505 registerCallback<HWC2_PFN_VSYNC>(Callback::Vsync, vsync_hook);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800506#else
507 sp<ComposerCallback> callback = new ComposerCallback(this);
508 mComposer->registerCallback(callback);
509#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700510}
511
512
513// For use by Display
514
515void Device::destroyVirtualDisplay(hwc2_display_t display)
516{
517 ALOGI("Destroying virtual display");
Chia-I Wuaab99f52016-10-05 12:59:58 +0800518#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700519 int32_t intError = mDestroyVirtualDisplay(mHwcDevice, display);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800520#else
521 auto intError = mComposer->destroyVirtualDisplay(display);
522#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700523 auto error = static_cast<Error>(intError);
524 ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64 ") failed:"
525 " %s (%d)", display, to_string(error).c_str(), intError);
Dan Stoza38628982016-07-13 15:48:58 -0700526 mDisplays.erase(display);
Dan Stoza651bf312015-10-23 17:03:17 -0700527}
528
529// Display methods
530
531Display::Display(Device& device, hwc2_display_t id)
532 : mDevice(device),
533 mId(id),
534 mIsConnected(false),
535 mIsVirtual(false)
536{
537 ALOGV("Created display %" PRIu64, id);
538}
539
540Display::~Display()
541{
542 ALOGV("Destroyed display %" PRIu64, mId);
543 if (mIsVirtual) {
544 mDevice.destroyVirtualDisplay(mId);
545 }
546}
547
548Display::Config::Config(Display& display, hwc2_config_t id)
549 : mDisplay(display),
550 mId(id),
551 mWidth(-1),
552 mHeight(-1),
553 mVsyncPeriod(-1),
554 mDpiX(-1),
555 mDpiY(-1) {}
556
557Display::Config::Builder::Builder(Display& display, hwc2_config_t id)
558 : mConfig(new Config(display, id)) {}
559
560float Display::Config::Builder::getDefaultDensity() {
561 // Default density is based on TVs: 1080p displays get XHIGH density, lower-
562 // resolution displays get TV density. Maybe eventually we'll need to update
563 // it for 4k displays, though hopefully those will just report accurate DPI
564 // information to begin with. This is also used for virtual displays and
565 // older HWC implementations, so be careful about orientation.
566
567 auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight);
568 if (longDimension >= 1080) {
569 return ACONFIGURATION_DENSITY_XHIGH;
570 } else {
571 return ACONFIGURATION_DENSITY_TV;
572 }
573}
574
575// Required by HWC2 display
576
577Error Display::acceptChanges()
578{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800579#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700580 int32_t intError = mDevice.mAcceptDisplayChanges(mDevice.mHwcDevice, mId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800581#else
582 auto intError = mDevice.mComposer->acceptDisplayChanges(mId);
583#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700584 return static_cast<Error>(intError);
585}
586
587Error Display::createLayer(std::shared_ptr<Layer>* outLayer)
588{
589 hwc2_layer_t layerId = 0;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800590#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700591 int32_t intError = mDevice.mCreateLayer(mDevice.mHwcDevice, mId, &layerId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800592#else
Chia-I Wu67e376d2016-12-19 11:36:22 +0800593 auto intError = mDevice.mComposer->createLayer(mId, &layerId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800594#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700595 auto error = static_cast<Error>(intError);
596 if (error != Error::None) {
597 return error;
598 }
599
600 auto layer = std::make_shared<Layer>(shared_from_this(), layerId);
601 mLayers.emplace(layerId, layer);
602 *outLayer = std::move(layer);
603 return Error::None;
604}
605
606Error Display::getActiveConfig(
607 std::shared_ptr<const Display::Config>* outConfig) const
608{
609 ALOGV("[%" PRIu64 "] getActiveConfig", mId);
610 hwc2_config_t configId = 0;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800611#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700612 int32_t intError = mDevice.mGetActiveConfig(mDevice.mHwcDevice, mId,
613 &configId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800614#else
Chia-I Wu67e376d2016-12-19 11:36:22 +0800615 auto intError = mDevice.mComposer->getActiveConfig(mId, &configId);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800616#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700617 auto error = static_cast<Error>(intError);
618
619 if (error != Error::None) {
Fabien Sanglardb7432cc2016-11-11 09:40:27 -0800620 ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId);
621 *outConfig = nullptr;
Dan Stoza651bf312015-10-23 17:03:17 -0700622 return error;
623 }
624
625 if (mConfigs.count(configId) != 0) {
626 *outConfig = mConfigs.at(configId);
627 } else {
628 ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId,
629 configId);
630 // Return no error, but the caller needs to check for a null pointer to
631 // detect this case
632 *outConfig = nullptr;
633 }
634
635 return Error::None;
636}
637
638Error Display::getChangedCompositionTypes(
639 std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes)
640{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800641#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700642 uint32_t numElements = 0;
643 int32_t intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice,
644 mId, &numElements, nullptr, nullptr);
645 auto error = static_cast<Error>(intError);
646 if (error != Error::None) {
647 return error;
648 }
649
650 std::vector<hwc2_layer_t> layerIds(numElements);
651 std::vector<int32_t> types(numElements);
652 intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice, mId,
653 &numElements, layerIds.data(), types.data());
Chia-I Wuaab99f52016-10-05 12:59:58 +0800654#else
655 std::vector<Hwc2::Layer> layerIds;
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800656 std::vector<Hwc2::IComposerClient::Composition> types;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800657 auto intError = mDevice.mComposer->getChangedCompositionTypes(mId,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800658 &layerIds, &types);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800659 uint32_t numElements = layerIds.size();
660 auto error = static_cast<Error>(intError);
661#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700662 error = static_cast<Error>(intError);
663 if (error != Error::None) {
664 return error;
665 }
666
667 outTypes->clear();
668 outTypes->reserve(numElements);
669 for (uint32_t element = 0; element < numElements; ++element) {
670 auto layer = getLayerById(layerIds[element]);
671 if (layer) {
672 auto type = static_cast<Composition>(types[element]);
673 ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s",
674 layer->getId(), to_string(type).c_str());
675 outTypes->emplace(layer, type);
676 } else {
677 ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found"
678 " on display %" PRIu64, layerIds[element], mId);
679 }
680 }
681
682 return Error::None;
683}
684
Michael Wright28f24d02016-07-12 13:30:53 -0700685Error Display::getColorModes(std::vector<android_color_mode_t>* outModes) const
Dan Stoza076ac672016-03-14 10:47:53 -0700686{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800687#ifdef BYPASS_IHWC
Dan Stoza076ac672016-03-14 10:47:53 -0700688 uint32_t numModes = 0;
689 int32_t intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId,
690 &numModes, nullptr);
691 auto error = static_cast<Error>(intError);
692 if (error != Error::None) {
693 return error;
694 }
695
696 std::vector<int32_t> modes(numModes);
697 intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId, &numModes,
698 modes.data());
699 error = static_cast<Error>(intError);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800700#else
701 std::vector<Hwc2::ColorMode> modes;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800702 auto intError = mDevice.mComposer->getColorModes(mId, &modes);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800703 uint32_t numModes = modes.size();
704 auto error = static_cast<Error>(intError);
705#endif
Dan Stoza076ac672016-03-14 10:47:53 -0700706 if (error != Error::None) {
707 return error;
708 }
709
Michael Wright28f24d02016-07-12 13:30:53 -0700710 outModes->resize(numModes);
711 for (size_t i = 0; i < numModes; i++) {
712 (*outModes)[i] = static_cast<android_color_mode_t>(modes[i]);
713 }
Dan Stoza076ac672016-03-14 10:47:53 -0700714 return Error::None;
715}
716
Dan Stoza651bf312015-10-23 17:03:17 -0700717std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const
718{
719 std::vector<std::shared_ptr<const Config>> configs;
720 for (const auto& element : mConfigs) {
721 configs.emplace_back(element.second);
722 }
723 return configs;
724}
725
726Error Display::getName(std::string* outName) const
727{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800728#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700729 uint32_t size;
730 int32_t intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size,
731 nullptr);
732 auto error = static_cast<Error>(intError);
733 if (error != Error::None) {
734 return error;
735 }
736
737 std::vector<char> rawName(size);
738 intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size,
739 rawName.data());
740 error = static_cast<Error>(intError);
741 if (error != Error::None) {
742 return error;
743 }
744
745 *outName = std::string(rawName.cbegin(), rawName.cend());
746 return Error::None;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800747#else
Chia-I Wu67e376d2016-12-19 11:36:22 +0800748 auto intError = mDevice.mComposer->getDisplayName(mId, outName);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800749 return static_cast<Error>(intError);
750#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700751}
752
753Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
754 std::unordered_map<std::shared_ptr<Layer>, LayerRequest>*
755 outLayerRequests)
756{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800757#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700758 int32_t intDisplayRequests = 0;
759 uint32_t numElements = 0;
760 int32_t intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId,
761 &intDisplayRequests, &numElements, nullptr, nullptr);
762 auto error = static_cast<Error>(intError);
763 if (error != Error::None) {
764 return error;
765 }
766
767 std::vector<hwc2_layer_t> layerIds(numElements);
768 std::vector<int32_t> layerRequests(numElements);
769 intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId,
770 &intDisplayRequests, &numElements, layerIds.data(),
771 layerRequests.data());
772 error = static_cast<Error>(intError);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800773#else
774 uint32_t intDisplayRequests;
775 std::vector<Hwc2::Layer> layerIds;
776 std::vector<uint32_t> layerRequests;
777 auto intError = mDevice.mComposer->getDisplayRequests(mId,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800778 &intDisplayRequests, &layerIds, &layerRequests);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800779 uint32_t numElements = layerIds.size();
780 auto error = static_cast<Error>(intError);
781#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700782 if (error != Error::None) {
783 return error;
784 }
785
786 *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests);
787 outLayerRequests->clear();
788 outLayerRequests->reserve(numElements);
789 for (uint32_t element = 0; element < numElements; ++element) {
790 auto layer = getLayerById(layerIds[element]);
791 if (layer) {
792 auto layerRequest =
793 static_cast<LayerRequest>(layerRequests[element]);
794 outLayerRequests->emplace(layer, layerRequest);
795 } else {
796 ALOGE("getRequests: invalid layer %" PRIu64 " found on display %"
797 PRIu64, layerIds[element], mId);
798 }
799 }
800
801 return Error::None;
802}
803
804Error Display::getType(DisplayType* outType) const
805{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800806#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700807 int32_t intType = 0;
808 int32_t intError = mDevice.mGetDisplayType(mDevice.mHwcDevice, mId,
809 &intType);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800810#else
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800811 Hwc2::IComposerClient::DisplayType intType =
812 Hwc2::IComposerClient::DisplayType::INVALID;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800813 auto intError = mDevice.mComposer->getDisplayType(mId, &intType);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800814#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700815 auto error = static_cast<Error>(intError);
816 if (error != Error::None) {
817 return error;
818 }
819
820 *outType = static_cast<DisplayType>(intType);
821 return Error::None;
822}
823
824Error Display::supportsDoze(bool* outSupport) const
825{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800826#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700827 int32_t intSupport = 0;
828 int32_t intError = mDevice.mGetDozeSupport(mDevice.mHwcDevice, mId,
829 &intSupport);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800830#else
831 bool intSupport = false;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800832 auto intError = mDevice.mComposer->getDozeSupport(mId, &intSupport);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800833#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700834 auto error = static_cast<Error>(intError);
835 if (error != Error::None) {
836 return error;
837 }
838 *outSupport = static_cast<bool>(intSupport);
839 return Error::None;
840}
841
Dan Stoza7d7ae732016-03-16 12:23:40 -0700842Error Display::getHdrCapabilities(
843 std::unique_ptr<HdrCapabilities>* outCapabilities) const
844{
845 uint32_t numTypes = 0;
846 float maxLuminance = -1.0f;
847 float maxAverageLuminance = -1.0f;
848 float minLuminance = -1.0f;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800849#ifdef BYPASS_IHWC
Dan Stoza7d7ae732016-03-16 12:23:40 -0700850 int32_t intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId,
851 &numTypes, nullptr, &maxLuminance, &maxAverageLuminance,
852 &minLuminance);
853 auto error = static_cast<HWC2::Error>(intError);
854 if (error != Error::None) {
855 return error;
856 }
857
858 std::vector<int32_t> types(numTypes);
859 intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId, &numTypes,
860 types.data(), &maxLuminance, &maxAverageLuminance, &minLuminance);
861 error = static_cast<HWC2::Error>(intError);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800862#else
863 std::vector<Hwc2::Hdr> intTypes;
Chia-I Wu67e376d2016-12-19 11:36:22 +0800864 auto intError = mDevice.mComposer->getHdrCapabilities(mId, &intTypes,
865 &maxLuminance, &maxAverageLuminance, &minLuminance);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800866 auto error = static_cast<HWC2::Error>(intError);
867
868 std::vector<int32_t> types;
869 for (auto type : intTypes) {
870 types.push_back(static_cast<int32_t>(type));
871 }
872 numTypes = types.size();
873#endif
Dan Stoza7d7ae732016-03-16 12:23:40 -0700874 if (error != Error::None) {
875 return error;
876 }
877
878 *outCapabilities = std::make_unique<HdrCapabilities>(std::move(types),
879 maxLuminance, maxAverageLuminance, minLuminance);
880 return Error::None;
881}
882
Dan Stoza651bf312015-10-23 17:03:17 -0700883Error Display::getReleaseFences(
884 std::unordered_map<std::shared_ptr<Layer>, sp<Fence>>* outFences) const
885{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800886#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700887 uint32_t numElements = 0;
888 int32_t intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId,
889 &numElements, nullptr, nullptr);
890 auto error = static_cast<Error>(intError);
891 if (error != Error::None) {
892 return error;
893 }
894
895 std::vector<hwc2_layer_t> layerIds(numElements);
896 std::vector<int32_t> fenceFds(numElements);
897 intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId, &numElements,
898 layerIds.data(), fenceFds.data());
899 error = static_cast<Error>(intError);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800900#else
901 std::vector<Hwc2::Layer> layerIds;
902 std::vector<int> fenceFds;
903 auto intError = mDevice.mComposer->getReleaseFences(mId,
Chia-I Wu67e376d2016-12-19 11:36:22 +0800904 &layerIds, &fenceFds);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800905 auto error = static_cast<Error>(intError);
906 uint32_t numElements = layerIds.size();
907#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700908 if (error != Error::None) {
909 return error;
910 }
911
912 std::unordered_map<std::shared_ptr<Layer>, sp<Fence>> releaseFences;
913 releaseFences.reserve(numElements);
914 for (uint32_t element = 0; element < numElements; ++element) {
915 auto layer = getLayerById(layerIds[element]);
916 if (layer) {
917 sp<Fence> fence(new Fence(fenceFds[element]));
918 releaseFences.emplace(std::move(layer), fence);
919 } else {
920 ALOGE("getReleaseFences: invalid layer %" PRIu64
921 " found on display %" PRIu64, layerIds[element], mId);
922 return Error::BadLayer;
923 }
924 }
925
926 *outFences = std::move(releaseFences);
927 return Error::None;
928}
929
Fabien Sanglard11d0fc32016-12-01 15:43:01 -0800930Error Display::present(sp<Fence>* outPresentFence)
Dan Stoza651bf312015-10-23 17:03:17 -0700931{
Naseer Ahmed847650b2016-06-17 11:14:25 -0400932 int32_t presentFenceFd = -1;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800933#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700934 int32_t intError = mDevice.mPresentDisplay(mDevice.mHwcDevice, mId,
Fabien Sanglard11d0fc32016-12-01 15:43:01 -0800935 &presentFenceFd);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800936#else
Chia-I Wu67e376d2016-12-19 11:36:22 +0800937 auto intError = mDevice.mComposer->presentDisplay(mId, &presentFenceFd);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800938#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700939 auto error = static_cast<Error>(intError);
940 if (error != Error::None) {
941 return error;
942 }
943
Fabien Sanglard11d0fc32016-12-01 15:43:01 -0800944 *outPresentFence = new Fence(presentFenceFd);
Dan Stoza651bf312015-10-23 17:03:17 -0700945 return Error::None;
946}
947
948Error Display::setActiveConfig(const std::shared_ptr<const Config>& config)
949{
950 if (config->getDisplayId() != mId) {
951 ALOGE("setActiveConfig received config %u for the wrong display %"
952 PRIu64 " (expected %" PRIu64 ")", config->getId(),
953 config->getDisplayId(), mId);
954 return Error::BadConfig;
955 }
Chia-I Wuaab99f52016-10-05 12:59:58 +0800956#ifdef BYPASS_IHWC
Dan Stoza651bf312015-10-23 17:03:17 -0700957 int32_t intError = mDevice.mSetActiveConfig(mDevice.mHwcDevice, mId,
958 config->getId());
Chia-I Wuaab99f52016-10-05 12:59:58 +0800959#else
960 auto intError = mDevice.mComposer->setActiveConfig(mId, config->getId());
961#endif
Dan Stoza651bf312015-10-23 17:03:17 -0700962 return static_cast<Error>(intError);
963}
964
965Error Display::setClientTarget(buffer_handle_t target,
966 const sp<Fence>& acquireFence, android_dataspace_t dataspace)
967{
Dan Stoza5cf424b2016-05-20 14:02:39 -0700968 // TODO: Properly encode client target surface damage
Dan Stoza651bf312015-10-23 17:03:17 -0700969 int32_t fenceFd = acquireFence->dup();
Chia-I Wuaab99f52016-10-05 12:59:58 +0800970#ifdef BYPASS_IHWC
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
974 auto intError = mDevice.mComposer->setClientTarget(mId, target, fenceFd,
975 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
1198Error Layer::setBuffer(buffer_handle_t buffer,
1199 const sp<Fence>& acquireFence)
1200{
1201 int32_t fenceFd = acquireFence->dup();
Chia-I Wuaab99f52016-10-05 12:59:58 +08001202#ifdef BYPASS_IHWC
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,
1207 mId, buffer, fenceFd);
1208#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