blob: 862dff138ec795ce8c28139ea5a13694ee249c14 [file] [log] [blame]
Chia-I Wu7f8d3962016-09-28 21:04:23 +08001/*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "HwcPassthrough"
18
Fabien Sanglard9b117a42017-03-21 09:39:35 -070019#include "Hwc.h"
Chia-I Wu7f8d3962016-09-28 21:04:23 +080020
Steven Thomas4492a302017-07-07 12:34:20 -070021#include <chrono>
Fabien Sanglard9b117a42017-03-21 09:39:35 -070022#include <type_traits>
Chia-I Wu7f8d3962016-09-28 21:04:23 +080023#include <log/log.h>
24
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -050025#include "ComposerClient.h"
Fabien Sanglard0d55a212017-03-16 16:56:46 -070026#include "hardware/hwcomposer.h"
27#include "hwc2on1adapter/HWC2On1Adapter.h"
Chia-I Wu7f8d3962016-09-28 21:04:23 +080028
Steven Thomas4492a302017-07-07 12:34:20 -070029using namespace std::chrono_literals;
30
Chia-I Wu7f8d3962016-09-28 21:04:23 +080031namespace android {
32namespace hardware {
33namespace graphics {
34namespace composer {
35namespace V2_1 {
36namespace implementation {
37
Fabien Sanglard0d55a212017-03-16 16:56:46 -070038
Chia-I Wu7f8d3962016-09-28 21:04:23 +080039HwcHal::HwcHal(const hw_module_t* module)
Fabien Sanglard0d55a212017-03-16 16:56:46 -070040 : mDevice(nullptr), mDispatch(), mAdapter()
Chia-I Wu7f8d3962016-09-28 21:04:23 +080041{
Fabien Sanglard0d55a212017-03-16 16:56:46 -070042 // Determine what kind of module is available (HWC2 vs HWC1.X).
43 hw_device_t* device = nullptr;
44 int error = module->methods->open(module, HWC_HARDWARE_COMPOSER, &device);
45 if (error != 0) {
46 ALOGE("Failed to open HWC device (%s), aborting", strerror(-error));
47 abort();
48 }
49 uint32_t majorVersion = (device->version >> 24) & 0xF;
50
51 // If we don't have a HWC2, we need to wrap whatever we have in an adapter.
52 if (majorVersion != 2) {
53 uint32_t minorVersion = device->version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK;
54 minorVersion = (minorVersion >> 16) & 0xF;
55 ALOGI("Found HWC implementation v%d.%d", majorVersion, minorVersion);
56 if (minorVersion < 1) {
57 ALOGE("Cannot adapt to HWC version %d.%d. Minimum supported is 1.1",
58 majorVersion, minorVersion);
59 abort();
60 }
61 mAdapter = std::make_unique<HWC2On1Adapter>(
62 reinterpret_cast<hwc_composer_device_1*>(device));
63
64 // Place the adapter in front of the device module.
65 mDevice = mAdapter.get();
66 } else {
67 mDevice = reinterpret_cast<hwc2_device_t*>(device);
Chia-I Wu7f8d3962016-09-28 21:04:23 +080068 }
69
70 initCapabilities();
Brian Anderson9af5d942017-04-04 16:16:41 -070071 if (majorVersion >= 2 &&
72 hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
73 ALOGE("Present fence must be reliable from HWC2 on.");
74 abort();
75 }
76
Chia-I Wu7f8d3962016-09-28 21:04:23 +080077 initDispatch();
78}
79
80HwcHal::~HwcHal()
81{
82 hwc2_close(mDevice);
Chia-I Wu7f8d3962016-09-28 21:04:23 +080083}
84
85void HwcHal::initCapabilities()
86{
87 uint32_t count = 0;
88 mDevice->getCapabilities(mDevice, &count, nullptr);
89
90 std::vector<Capability> caps(count);
91 mDevice->getCapabilities(mDevice, &count, reinterpret_cast<
92 std::underlying_type<Capability>::type*>(caps.data()));
93 caps.resize(count);
94
95 mCapabilities.insert(caps.cbegin(), caps.cend());
96}
97
98template<typename T>
Chia-I Wue1768352016-12-19 12:56:54 +080099void HwcHal::initDispatch(hwc2_function_descriptor_t desc, T* outPfn)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800100{
101 auto pfn = mDevice->getFunction(mDevice, desc);
102 if (!pfn) {
103 LOG_ALWAYS_FATAL("failed to get hwcomposer2 function %d", desc);
104 }
105
Chia-I Wue1768352016-12-19 12:56:54 +0800106 *outPfn = reinterpret_cast<T>(pfn);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800107}
108
109void HwcHal::initDispatch()
110{
Chia-I Wue1768352016-12-19 12:56:54 +0800111 initDispatch(HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES,
112 &mDispatch.acceptDisplayChanges);
113 initDispatch(HWC2_FUNCTION_CREATE_LAYER, &mDispatch.createLayer);
114 initDispatch(HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY,
115 &mDispatch.createVirtualDisplay);
116 initDispatch(HWC2_FUNCTION_DESTROY_LAYER, &mDispatch.destroyLayer);
117 initDispatch(HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY,
118 &mDispatch.destroyVirtualDisplay);
119 initDispatch(HWC2_FUNCTION_DUMP, &mDispatch.dump);
120 initDispatch(HWC2_FUNCTION_GET_ACTIVE_CONFIG, &mDispatch.getActiveConfig);
121 initDispatch(HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES,
122 &mDispatch.getChangedCompositionTypes);
123 initDispatch(HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT,
124 &mDispatch.getClientTargetSupport);
125 initDispatch(HWC2_FUNCTION_GET_COLOR_MODES, &mDispatch.getColorModes);
126 initDispatch(HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE,
127 &mDispatch.getDisplayAttribute);
128 initDispatch(HWC2_FUNCTION_GET_DISPLAY_CONFIGS,
129 &mDispatch.getDisplayConfigs);
130 initDispatch(HWC2_FUNCTION_GET_DISPLAY_NAME, &mDispatch.getDisplayName);
131 initDispatch(HWC2_FUNCTION_GET_DISPLAY_REQUESTS,
132 &mDispatch.getDisplayRequests);
133 initDispatch(HWC2_FUNCTION_GET_DISPLAY_TYPE, &mDispatch.getDisplayType);
134 initDispatch(HWC2_FUNCTION_GET_DOZE_SUPPORT, &mDispatch.getDozeSupport);
135 initDispatch(HWC2_FUNCTION_GET_HDR_CAPABILITIES,
136 &mDispatch.getHdrCapabilities);
137 initDispatch(HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT,
138 &mDispatch.getMaxVirtualDisplayCount);
139 initDispatch(HWC2_FUNCTION_GET_RELEASE_FENCES,
140 &mDispatch.getReleaseFences);
141 initDispatch(HWC2_FUNCTION_PRESENT_DISPLAY, &mDispatch.presentDisplay);
142 initDispatch(HWC2_FUNCTION_REGISTER_CALLBACK,
143 &mDispatch.registerCallback);
144 initDispatch(HWC2_FUNCTION_SET_ACTIVE_CONFIG, &mDispatch.setActiveConfig);
145 initDispatch(HWC2_FUNCTION_SET_CLIENT_TARGET, &mDispatch.setClientTarget);
146 initDispatch(HWC2_FUNCTION_SET_COLOR_MODE, &mDispatch.setColorMode);
147 initDispatch(HWC2_FUNCTION_SET_COLOR_TRANSFORM,
148 &mDispatch.setColorTransform);
149 initDispatch(HWC2_FUNCTION_SET_CURSOR_POSITION,
150 &mDispatch.setCursorPosition);
151 initDispatch(HWC2_FUNCTION_SET_LAYER_BLEND_MODE,
152 &mDispatch.setLayerBlendMode);
153 initDispatch(HWC2_FUNCTION_SET_LAYER_BUFFER, &mDispatch.setLayerBuffer);
154 initDispatch(HWC2_FUNCTION_SET_LAYER_COLOR, &mDispatch.setLayerColor);
155 initDispatch(HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE,
156 &mDispatch.setLayerCompositionType);
157 initDispatch(HWC2_FUNCTION_SET_LAYER_DATASPACE,
158 &mDispatch.setLayerDataspace);
159 initDispatch(HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME,
160 &mDispatch.setLayerDisplayFrame);
161 initDispatch(HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA,
162 &mDispatch.setLayerPlaneAlpha);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800163
164 if (hasCapability(Capability::SIDEBAND_STREAM)) {
Chia-I Wue1768352016-12-19 12:56:54 +0800165 initDispatch(HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM,
166 &mDispatch.setLayerSidebandStream);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800167 }
168
Chia-I Wue1768352016-12-19 12:56:54 +0800169 initDispatch(HWC2_FUNCTION_SET_LAYER_SOURCE_CROP,
170 &mDispatch.setLayerSourceCrop);
171 initDispatch(HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE,
172 &mDispatch.setLayerSurfaceDamage);
173 initDispatch(HWC2_FUNCTION_SET_LAYER_TRANSFORM,
174 &mDispatch.setLayerTransform);
175 initDispatch(HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION,
176 &mDispatch.setLayerVisibleRegion);
177 initDispatch(HWC2_FUNCTION_SET_LAYER_Z_ORDER, &mDispatch.setLayerZOrder);
178 initDispatch(HWC2_FUNCTION_SET_OUTPUT_BUFFER, &mDispatch.setOutputBuffer);
179 initDispatch(HWC2_FUNCTION_SET_POWER_MODE, &mDispatch.setPowerMode);
180 initDispatch(HWC2_FUNCTION_SET_VSYNC_ENABLED, &mDispatch.setVsyncEnabled);
181 initDispatch(HWC2_FUNCTION_VALIDATE_DISPLAY, &mDispatch.validateDisplay);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800182}
183
184bool HwcHal::hasCapability(Capability capability) const
185{
186 return (mCapabilities.count(capability) > 0);
187}
188
189Return<void> HwcHal::getCapabilities(getCapabilities_cb hidl_cb)
190{
191 std::vector<Capability> caps(
192 mCapabilities.cbegin(), mCapabilities.cend());
193
194 hidl_vec<Capability> caps_reply;
195 caps_reply.setToExternal(caps.data(), caps.size());
196 hidl_cb(caps_reply);
197
198 return Void();
199}
200
201Return<void> HwcHal::dumpDebugInfo(dumpDebugInfo_cb hidl_cb)
202{
Chia-I Wue1768352016-12-19 12:56:54 +0800203 uint32_t len = 0;
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800204 mDispatch.dump(mDevice, &len, nullptr);
205
206 std::vector<char> buf(len + 1);
207 mDispatch.dump(mDevice, &len, buf.data());
208 buf.resize(len + 1);
209 buf[len] = '\0';
210
211 hidl_string buf_reply;
212 buf_reply.setToExternal(buf.data(), len);
213 hidl_cb(buf_reply);
214
215 return Void();
216}
217
Chia-I Wubb61a722016-10-24 15:40:20 +0800218Return<void> HwcHal::createClient(createClient_cb hidl_cb)
219{
220 Error err = Error::NONE;
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500221 sp<ComposerClient> client;
Chia-I Wubb61a722016-10-24 15:40:20 +0800222
223 {
Steven Thomas4492a302017-07-07 12:34:20 -0700224 std::unique_lock<std::mutex> lock(mClientMutex);
225
226 if (mClient != nullptr) {
227 // In surface flinger we delete a composer client on one thread and
228 // then create a new client on another thread. Although surface
229 // flinger ensures the calls are made in that sequence (destroy and
230 // then create), sometimes the calls land in the composer service
231 // inverted (create and then destroy). Wait for a brief period to
232 // see if the existing client is destroyed.
233 ALOGI("HwcHal::createClient: Client already exists. Waiting for"
234 " it to be destroyed.");
235 mClientDestroyedWait.wait_for(lock, 1s,
236 [this] { return mClient == nullptr; });
237 std::string doneMsg = mClient == nullptr ?
238 "Existing client was destroyed." :
239 "Existing client was never destroyed!";
240 ALOGI("HwcHal::createClient: Done waiting. %s", doneMsg.c_str());
241 }
Chia-I Wubb61a722016-10-24 15:40:20 +0800242
243 // only one client is allowed
244 if (mClient == nullptr) {
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500245 client = new ComposerClient(*this);
246 client->initialize();
Chia-I Wubb61a722016-10-24 15:40:20 +0800247 mClient = client;
248 } else {
249 err = Error::NO_RESOURCES;
250 }
251 }
252
253 hidl_cb(err, client);
254
255 return Void();
256}
257
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500258sp<ComposerClient> HwcHal::getClient()
Chia-I Wubb61a722016-10-24 15:40:20 +0800259{
260 std::lock_guard<std::mutex> lock(mClientMutex);
261 return (mClient != nullptr) ? mClient.promote() : nullptr;
262}
263
264void HwcHal::removeClient()
265{
266 std::lock_guard<std::mutex> lock(mClientMutex);
267 mClient = nullptr;
Steven Thomas4492a302017-07-07 12:34:20 -0700268 mClientDestroyedWait.notify_all();
Chia-I Wubb61a722016-10-24 15:40:20 +0800269}
270
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800271void HwcHal::hotplugHook(hwc2_callback_data_t callbackData,
272 hwc2_display_t display, int32_t connected)
273{
274 auto hal = reinterpret_cast<HwcHal*>(callbackData);
Chia-I Wubb61a722016-10-24 15:40:20 +0800275 auto client = hal->getClient();
276 if (client != nullptr) {
277 client->onHotplug(display,
278 static_cast<IComposerCallback::Connection>(connected));
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800279 }
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800280}
281
282void HwcHal::refreshHook(hwc2_callback_data_t callbackData,
283 hwc2_display_t display)
284{
285 auto hal = reinterpret_cast<HwcHal*>(callbackData);
Chia-I Wubb61a722016-10-24 15:40:20 +0800286 auto client = hal->getClient();
287 if (client != nullptr) {
288 client->onRefresh(display);
289 }
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800290}
291
292void HwcHal::vsyncHook(hwc2_callback_data_t callbackData,
293 hwc2_display_t display, int64_t timestamp)
294{
295 auto hal = reinterpret_cast<HwcHal*>(callbackData);
Chia-I Wubb61a722016-10-24 15:40:20 +0800296 auto client = hal->getClient();
297 if (client != nullptr) {
298 client->onVsync(display, timestamp);
299 }
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800300}
301
Chia-I Wubb61a722016-10-24 15:40:20 +0800302void HwcHal::enableCallback(bool enable)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800303{
Chia-I Wubb61a722016-10-24 15:40:20 +0800304 if (enable) {
305 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
306 reinterpret_cast<hwc2_function_pointer_t>(hotplugHook));
307 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
308 reinterpret_cast<hwc2_function_pointer_t>(refreshHook));
309 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
310 reinterpret_cast<hwc2_function_pointer_t>(vsyncHook));
311 } else {
312 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
313 nullptr);
314 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
315 nullptr);
316 mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
317 nullptr);
318 }
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800319}
320
Chia-I Wubb61a722016-10-24 15:40:20 +0800321uint32_t HwcHal::getMaxVirtualDisplayCount()
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800322{
323 return mDispatch.getMaxVirtualDisplayCount(mDevice);
324}
325
Chia-I Wubb61a722016-10-24 15:40:20 +0800326Error HwcHal::createVirtualDisplay(uint32_t width, uint32_t height,
Chia-I Wue1768352016-12-19 12:56:54 +0800327 PixelFormat* format, Display* outDisplay)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800328{
Chia-I Wue1768352016-12-19 12:56:54 +0800329 int32_t hwc_format = static_cast<int32_t>(*format);
Chia-I Wubb61a722016-10-24 15:40:20 +0800330 int32_t err = mDispatch.createVirtualDisplay(mDevice, width, height,
Chia-I Wue1768352016-12-19 12:56:54 +0800331 &hwc_format, outDisplay);
332 *format = static_cast<PixelFormat>(hwc_format);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800333
Chia-I Wubb61a722016-10-24 15:40:20 +0800334 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800335}
336
Chia-I Wubb61a722016-10-24 15:40:20 +0800337Error HwcHal::destroyVirtualDisplay(Display display)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800338{
Chia-I Wubb61a722016-10-24 15:40:20 +0800339 int32_t err = mDispatch.destroyVirtualDisplay(mDevice, display);
340 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800341}
342
Chia-I Wue1768352016-12-19 12:56:54 +0800343Error HwcHal::createLayer(Display display, Layer* outLayer)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800344{
Chia-I Wue1768352016-12-19 12:56:54 +0800345 int32_t err = mDispatch.createLayer(mDevice, display, outLayer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800346 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800347}
348
Chia-I Wubb61a722016-10-24 15:40:20 +0800349Error HwcHal::destroyLayer(Display display, Layer layer)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800350{
Chia-I Wubb61a722016-10-24 15:40:20 +0800351 int32_t err = mDispatch.destroyLayer(mDevice, display, layer);
352 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800353}
354
Chia-I Wue1768352016-12-19 12:56:54 +0800355Error HwcHal::getActiveConfig(Display display, Config* outConfig)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800356{
Chia-I Wue1768352016-12-19 12:56:54 +0800357 int32_t err = mDispatch.getActiveConfig(mDevice, display, outConfig);
Chia-I Wubb61a722016-10-24 15:40:20 +0800358 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800359}
360
Chia-I Wubb61a722016-10-24 15:40:20 +0800361Error HwcHal::getClientTargetSupport(Display display,
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800362 uint32_t width, uint32_t height,
363 PixelFormat format, Dataspace dataspace)
364{
Chia-I Wubb61a722016-10-24 15:40:20 +0800365 int32_t err = mDispatch.getClientTargetSupport(mDevice, display,
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800366 width, height, static_cast<int32_t>(format),
367 static_cast<int32_t>(dataspace));
Chia-I Wubb61a722016-10-24 15:40:20 +0800368 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800369}
370
Chia-I Wue1768352016-12-19 12:56:54 +0800371Error HwcHal::getColorModes(Display display, hidl_vec<ColorMode>* outModes)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800372{
373 uint32_t count = 0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800374 int32_t err = mDispatch.getColorModes(mDevice, display, &count, nullptr);
375 if (err != HWC2_ERROR_NONE) {
376 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800377 }
378
Chia-I Wue1768352016-12-19 12:56:54 +0800379 outModes->resize(count);
Chia-I Wubb61a722016-10-24 15:40:20 +0800380 err = mDispatch.getColorModes(mDevice, display, &count,
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800381 reinterpret_cast<std::underlying_type<ColorMode>::type*>(
Chia-I Wue1768352016-12-19 12:56:54 +0800382 outModes->data()));
Chia-I Wubb61a722016-10-24 15:40:20 +0800383 if (err != HWC2_ERROR_NONE) {
Chia-I Wue1768352016-12-19 12:56:54 +0800384 *outModes = hidl_vec<ColorMode>();
Chia-I Wubb61a722016-10-24 15:40:20 +0800385 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800386 }
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800387
Chia-I Wubb61a722016-10-24 15:40:20 +0800388 return Error::NONE;
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800389}
390
Chia-I Wubb61a722016-10-24 15:40:20 +0800391Error HwcHal::getDisplayAttribute(Display display, Config config,
Chia-I Wue1768352016-12-19 12:56:54 +0800392 IComposerClient::Attribute attribute, int32_t* outValue)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800393{
Chia-I Wubb61a722016-10-24 15:40:20 +0800394 int32_t err = mDispatch.getDisplayAttribute(mDevice, display, config,
Chia-I Wue1768352016-12-19 12:56:54 +0800395 static_cast<int32_t>(attribute), outValue);
Chia-I Wubb61a722016-10-24 15:40:20 +0800396 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800397}
398
Chia-I Wue1768352016-12-19 12:56:54 +0800399Error HwcHal::getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800400{
401 uint32_t count = 0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800402 int32_t err = mDispatch.getDisplayConfigs(mDevice, display,
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800403 &count, nullptr);
Chia-I Wubb61a722016-10-24 15:40:20 +0800404 if (err != HWC2_ERROR_NONE) {
405 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800406 }
407
Chia-I Wue1768352016-12-19 12:56:54 +0800408 outConfigs->resize(count);
Chia-I Wubb61a722016-10-24 15:40:20 +0800409 err = mDispatch.getDisplayConfigs(mDevice, display,
Chia-I Wue1768352016-12-19 12:56:54 +0800410 &count, outConfigs->data());
Chia-I Wubb61a722016-10-24 15:40:20 +0800411 if (err != HWC2_ERROR_NONE) {
Chia-I Wue1768352016-12-19 12:56:54 +0800412 *outConfigs = hidl_vec<Config>();
Chia-I Wubb61a722016-10-24 15:40:20 +0800413 return static_cast<Error>(err);
414 }
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800415
Chia-I Wubb61a722016-10-24 15:40:20 +0800416 return Error::NONE;
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800417}
418
Chia-I Wue1768352016-12-19 12:56:54 +0800419Error HwcHal::getDisplayName(Display display, hidl_string* outName)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800420{
421 uint32_t count = 0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800422 int32_t err = mDispatch.getDisplayName(mDevice, display, &count, nullptr);
423 if (err != HWC2_ERROR_NONE) {
424 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800425 }
426
Chia-I Wubb61a722016-10-24 15:40:20 +0800427 std::vector<char> buf(count + 1);
428 err = mDispatch.getDisplayName(mDevice, display, &count, buf.data());
429 if (err != HWC2_ERROR_NONE) {
430 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800431 }
Chia-I Wubb61a722016-10-24 15:40:20 +0800432 buf.resize(count + 1);
433 buf[count] = '\0';
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800434
Chia-I Wue1768352016-12-19 12:56:54 +0800435 *outName = buf.data();
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800436
Chia-I Wubb61a722016-10-24 15:40:20 +0800437 return Error::NONE;
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800438}
439
Chia-I Wue1768352016-12-19 12:56:54 +0800440Error HwcHal::getDisplayType(Display display,
441 IComposerClient::DisplayType* outType)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800442{
Chia-I Wubb61a722016-10-24 15:40:20 +0800443 int32_t hwc_type = HWC2_DISPLAY_TYPE_INVALID;
444 int32_t err = mDispatch.getDisplayType(mDevice, display, &hwc_type);
Chia-I Wue1768352016-12-19 12:56:54 +0800445 *outType = static_cast<IComposerClient::DisplayType>(hwc_type);
Chia-I Wubb61a722016-10-24 15:40:20 +0800446
447 return static_cast<Error>(err);
448}
449
Chia-I Wue1768352016-12-19 12:56:54 +0800450Error HwcHal::getDozeSupport(Display display, bool* outSupport)
Chia-I Wubb61a722016-10-24 15:40:20 +0800451{
452 int32_t hwc_support = 0;
453 int32_t err = mDispatch.getDozeSupport(mDevice, display, &hwc_support);
Chia-I Wue1768352016-12-19 12:56:54 +0800454 *outSupport = hwc_support;
Chia-I Wubb61a722016-10-24 15:40:20 +0800455
456 return static_cast<Error>(err);
457}
458
Chia-I Wue1768352016-12-19 12:56:54 +0800459Error HwcHal::getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
460 float* outMaxLuminance, float* outMaxAverageLuminance,
461 float* outMinLuminance)
Chia-I Wubb61a722016-10-24 15:40:20 +0800462{
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800463 uint32_t count = 0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800464 int32_t err = mDispatch.getHdrCapabilities(mDevice, display, &count,
Chia-I Wue1768352016-12-19 12:56:54 +0800465 nullptr, outMaxLuminance, outMaxAverageLuminance,
466 outMinLuminance);
Chia-I Wubb61a722016-10-24 15:40:20 +0800467 if (err != HWC2_ERROR_NONE) {
468 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800469 }
470
Chia-I Wue1768352016-12-19 12:56:54 +0800471 outTypes->resize(count);
Chia-I Wubb61a722016-10-24 15:40:20 +0800472 err = mDispatch.getHdrCapabilities(mDevice, display, &count,
Chia-I Wue1768352016-12-19 12:56:54 +0800473 reinterpret_cast<std::underlying_type<Hdr>::type*>(
474 outTypes->data()), outMaxLuminance,
475 outMaxAverageLuminance, outMinLuminance);
Chia-I Wubb61a722016-10-24 15:40:20 +0800476 if (err != HWC2_ERROR_NONE) {
Chia-I Wue1768352016-12-19 12:56:54 +0800477 *outTypes = hidl_vec<Hdr>();
Chia-I Wubb61a722016-10-24 15:40:20 +0800478 return static_cast<Error>(err);
479 }
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800480
Chia-I Wubb61a722016-10-24 15:40:20 +0800481 return Error::NONE;
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800482}
483
Chia-I Wubb61a722016-10-24 15:40:20 +0800484Error HwcHal::setActiveConfig(Display display, Config config)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800485{
Chia-I Wubb61a722016-10-24 15:40:20 +0800486 int32_t err = mDispatch.setActiveConfig(mDevice, display, config);
487 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800488}
489
Chia-I Wubb61a722016-10-24 15:40:20 +0800490Error HwcHal::setColorMode(Display display, ColorMode mode)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800491{
Chia-I Wubb61a722016-10-24 15:40:20 +0800492 int32_t err = mDispatch.setColorMode(mDevice, display,
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800493 static_cast<int32_t>(mode));
Chia-I Wubb61a722016-10-24 15:40:20 +0800494 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800495}
496
Chia-I Wubb61a722016-10-24 15:40:20 +0800497Error HwcHal::setPowerMode(Display display, IComposerClient::PowerMode mode)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800498{
Chia-I Wubb61a722016-10-24 15:40:20 +0800499 int32_t err = mDispatch.setPowerMode(mDevice, display,
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800500 static_cast<int32_t>(mode));
Chia-I Wubb61a722016-10-24 15:40:20 +0800501 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800502}
503
Chia-I Wubb61a722016-10-24 15:40:20 +0800504Error HwcHal::setVsyncEnabled(Display display, IComposerClient::Vsync enabled)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800505{
Chia-I Wubb61a722016-10-24 15:40:20 +0800506 int32_t err = mDispatch.setVsyncEnabled(mDevice, display,
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800507 static_cast<int32_t>(enabled));
Chia-I Wubb61a722016-10-24 15:40:20 +0800508 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800509}
510
Chia-I Wubb61a722016-10-24 15:40:20 +0800511Error HwcHal::setColorTransform(Display display, const float* matrix,
512 int32_t hint)
513{
514 int32_t err = mDispatch.setColorTransform(mDevice, display, matrix, hint);
515 return static_cast<Error>(err);
516}
517
518Error HwcHal::setClientTarget(Display display, buffer_handle_t target,
519 int32_t acquireFence, int32_t dataspace,
520 const std::vector<hwc_rect_t>& damage)
521{
522 hwc_region region = { damage.size(), damage.data() };
523 int32_t err = mDispatch.setClientTarget(mDevice, display, target,
524 acquireFence, dataspace, region);
525 return static_cast<Error>(err);
526}
527
528Error HwcHal::setOutputBuffer(Display display, buffer_handle_t buffer,
529 int32_t releaseFence)
530{
531 int32_t err = mDispatch.setOutputBuffer(mDevice, display, buffer,
532 releaseFence);
533 // unlike in setClientTarget, releaseFence is owned by us
534 if (err == HWC2_ERROR_NONE && releaseFence >= 0) {
535 close(releaseFence);
536 }
537
538 return static_cast<Error>(err);
539}
540
541Error HwcHal::validateDisplay(Display display,
Chia-I Wue1768352016-12-19 12:56:54 +0800542 std::vector<Layer>* outChangedLayers,
543 std::vector<IComposerClient::Composition>* outCompositionTypes,
544 uint32_t* outDisplayRequestMask,
545 std::vector<Layer>* outRequestedLayers,
546 std::vector<uint32_t>* outRequestMasks)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800547{
548 uint32_t types_count = 0;
549 uint32_t reqs_count = 0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800550 int32_t err = mDispatch.validateDisplay(mDevice, display,
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800551 &types_count, &reqs_count);
Chia-I Wubb61a722016-10-24 15:40:20 +0800552 if (err != HWC2_ERROR_NONE && err != HWC2_ERROR_HAS_CHANGES) {
553 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800554 }
555
Chia-I Wubb61a722016-10-24 15:40:20 +0800556 err = mDispatch.getChangedCompositionTypes(mDevice, display,
557 &types_count, nullptr, nullptr);
558 if (err != HWC2_ERROR_NONE) {
559 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800560 }
561
Chia-I Wue1768352016-12-19 12:56:54 +0800562 outChangedLayers->resize(types_count);
563 outCompositionTypes->resize(types_count);
Chia-I Wubb61a722016-10-24 15:40:20 +0800564 err = mDispatch.getChangedCompositionTypes(mDevice, display,
Chia-I Wue1768352016-12-19 12:56:54 +0800565 &types_count, outChangedLayers->data(),
Chia-I Wubb61a722016-10-24 15:40:20 +0800566 reinterpret_cast<
567 std::underlying_type<IComposerClient::Composition>::type*>(
Chia-I Wue1768352016-12-19 12:56:54 +0800568 outCompositionTypes->data()));
Chia-I Wubb61a722016-10-24 15:40:20 +0800569 if (err != HWC2_ERROR_NONE) {
Chia-I Wue1768352016-12-19 12:56:54 +0800570 outChangedLayers->clear();
571 outCompositionTypes->clear();
Chia-I Wubb61a722016-10-24 15:40:20 +0800572 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800573 }
574
Chia-I Wubb61a722016-10-24 15:40:20 +0800575 int32_t display_reqs = 0;
576 err = mDispatch.getDisplayRequests(mDevice, display, &display_reqs,
577 &reqs_count, nullptr, nullptr);
578 if (err != HWC2_ERROR_NONE) {
Chia-I Wue1768352016-12-19 12:56:54 +0800579 outChangedLayers->clear();
580 outCompositionTypes->clear();
Chia-I Wubb61a722016-10-24 15:40:20 +0800581 return static_cast<Error>(err);
582 }
583
Chia-I Wue1768352016-12-19 12:56:54 +0800584 outRequestedLayers->resize(reqs_count);
585 outRequestMasks->resize(reqs_count);
Chia-I Wubb61a722016-10-24 15:40:20 +0800586 err = mDispatch.getDisplayRequests(mDevice, display, &display_reqs,
Chia-I Wue1768352016-12-19 12:56:54 +0800587 &reqs_count, outRequestedLayers->data(),
588 reinterpret_cast<int32_t*>(outRequestMasks->data()));
Chia-I Wubb61a722016-10-24 15:40:20 +0800589 if (err != HWC2_ERROR_NONE) {
Chia-I Wue1768352016-12-19 12:56:54 +0800590 outChangedLayers->clear();
591 outCompositionTypes->clear();
Chia-I Wubb61a722016-10-24 15:40:20 +0800592
Chia-I Wue1768352016-12-19 12:56:54 +0800593 outRequestedLayers->clear();
594 outRequestMasks->clear();
Chia-I Wubb61a722016-10-24 15:40:20 +0800595 return static_cast<Error>(err);
596 }
597
Chia-I Wue1768352016-12-19 12:56:54 +0800598 *outDisplayRequestMask = display_reqs;
Chia-I Wubb61a722016-10-24 15:40:20 +0800599
600 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800601}
602
Chia-I Wubb61a722016-10-24 15:40:20 +0800603Error HwcHal::acceptDisplayChanges(Display display)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800604{
Chia-I Wubb61a722016-10-24 15:40:20 +0800605 int32_t err = mDispatch.acceptDisplayChanges(mDevice, display);
606 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800607}
608
Chia-I Wue1768352016-12-19 12:56:54 +0800609Error HwcHal::presentDisplay(Display display, int32_t* outPresentFence,
610 std::vector<Layer>* outLayers, std::vector<int32_t>* outReleaseFences)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800611{
Chia-I Wue1768352016-12-19 12:56:54 +0800612 *outPresentFence = -1;
613 int32_t err = mDispatch.presentDisplay(mDevice, display, outPresentFence);
Chia-I Wubb61a722016-10-24 15:40:20 +0800614 if (err != HWC2_ERROR_NONE) {
615 return static_cast<Error>(err);
616 }
617
618 uint32_t count = 0;
619 err = mDispatch.getReleaseFences(mDevice, display, &count,
620 nullptr, nullptr);
621 if (err != HWC2_ERROR_NONE) {
622 ALOGW("failed to get release fences");
623 return Error::NONE;
624 }
625
Chia-I Wue1768352016-12-19 12:56:54 +0800626 outLayers->resize(count);
627 outReleaseFences->resize(count);
Chia-I Wubb61a722016-10-24 15:40:20 +0800628 err = mDispatch.getReleaseFences(mDevice, display, &count,
Chia-I Wue1768352016-12-19 12:56:54 +0800629 outLayers->data(), outReleaseFences->data());
Chia-I Wubb61a722016-10-24 15:40:20 +0800630 if (err != HWC2_ERROR_NONE) {
631 ALOGW("failed to get release fences");
Chia-I Wue1768352016-12-19 12:56:54 +0800632 outLayers->clear();
633 outReleaseFences->clear();
Chia-I Wubb61a722016-10-24 15:40:20 +0800634 return Error::NONE;
635 }
636
637 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800638}
639
Chia-I Wubb61a722016-10-24 15:40:20 +0800640Error HwcHal::setLayerCursorPosition(Display display, Layer layer,
641 int32_t x, int32_t y)
642{
643 int32_t err = mDispatch.setCursorPosition(mDevice, display, layer, x, y);
644 return static_cast<Error>(err);
645}
646
647Error HwcHal::setLayerBuffer(Display display, Layer layer,
648 buffer_handle_t buffer, int32_t acquireFence)
649{
650 int32_t err = mDispatch.setLayerBuffer(mDevice, display, layer,
651 buffer, acquireFence);
652 return static_cast<Error>(err);
653}
654
655Error HwcHal::setLayerSurfaceDamage(Display display, Layer layer,
656 const std::vector<hwc_rect_t>& damage)
657{
658 hwc_region region = { damage.size(), damage.data() };
659 int32_t err = mDispatch.setLayerSurfaceDamage(mDevice, display, layer,
660 region);
661 return static_cast<Error>(err);
662}
663
664Error HwcHal::setLayerBlendMode(Display display, Layer layer, int32_t mode)
665{
666 int32_t err = mDispatch.setLayerBlendMode(mDevice, display, layer, mode);
667 return static_cast<Error>(err);
668}
669
670Error HwcHal::setLayerColor(Display display, Layer layer,
671 IComposerClient::Color color)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800672{
673 hwc_color_t hwc_color{color.r, color.g, color.b, color.a};
Chia-I Wubb61a722016-10-24 15:40:20 +0800674 int32_t err = mDispatch.setLayerColor(mDevice, display, layer, hwc_color);
675 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800676}
677
Chia-I Wubb61a722016-10-24 15:40:20 +0800678Error HwcHal::setLayerCompositionType(Display display, Layer layer,
679 int32_t type)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800680{
Chia-I Wubb61a722016-10-24 15:40:20 +0800681 int32_t err = mDispatch.setLayerCompositionType(mDevice, display, layer,
682 type);
683 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800684}
685
Chia-I Wubb61a722016-10-24 15:40:20 +0800686Error HwcHal::setLayerDataspace(Display display, Layer layer,
687 int32_t dataspace)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800688{
Chia-I Wubb61a722016-10-24 15:40:20 +0800689 int32_t err = mDispatch.setLayerDataspace(mDevice, display, layer,
690 dataspace);
691 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800692}
693
Chia-I Wubb61a722016-10-24 15:40:20 +0800694Error HwcHal::setLayerDisplayFrame(Display display, Layer layer,
695 const hwc_rect_t& frame)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800696{
Chia-I Wubb61a722016-10-24 15:40:20 +0800697 int32_t err = mDispatch.setLayerDisplayFrame(mDevice, display, layer,
698 frame);
699 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800700}
701
Chia-I Wubb61a722016-10-24 15:40:20 +0800702Error HwcHal::setLayerPlaneAlpha(Display display, Layer layer, float alpha)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800703{
Chia-I Wubb61a722016-10-24 15:40:20 +0800704 int32_t err = mDispatch.setLayerPlaneAlpha(mDevice, display, layer,
705 alpha);
706 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800707}
708
Chia-I Wubb61a722016-10-24 15:40:20 +0800709Error HwcHal::setLayerSidebandStream(Display display, Layer layer,
710 buffer_handle_t stream)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800711{
Chia-I Wubb61a722016-10-24 15:40:20 +0800712 int32_t err = mDispatch.setLayerSidebandStream(mDevice, display, layer,
713 stream);
714 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800715}
716
Chia-I Wubb61a722016-10-24 15:40:20 +0800717Error HwcHal::setLayerSourceCrop(Display display, Layer layer,
718 const hwc_frect_t& crop)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800719{
Chia-I Wubb61a722016-10-24 15:40:20 +0800720 int32_t err = mDispatch.setLayerSourceCrop(mDevice, display, layer, crop);
721 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800722}
723
Chia-I Wubb61a722016-10-24 15:40:20 +0800724Error HwcHal::setLayerTransform(Display display, Layer layer,
725 int32_t transform)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800726{
Chia-I Wubb61a722016-10-24 15:40:20 +0800727 int32_t err = mDispatch.setLayerTransform(mDevice, display, layer,
728 transform);
729 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800730}
731
Chia-I Wubb61a722016-10-24 15:40:20 +0800732Error HwcHal::setLayerVisibleRegion(Display display, Layer layer,
733 const std::vector<hwc_rect_t>& visible)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800734{
Chia-I Wubb61a722016-10-24 15:40:20 +0800735 hwc_region_t region = { visible.size(), visible.data() };
736 int32_t err = mDispatch.setLayerVisibleRegion(mDevice, display, layer,
737 region);
738 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800739}
740
Chia-I Wubb61a722016-10-24 15:40:20 +0800741Error HwcHal::setLayerZOrder(Display display, Layer layer, uint32_t z)
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800742{
Chia-I Wubb61a722016-10-24 15:40:20 +0800743 int32_t err = mDispatch.setLayerZOrder(mDevice, display, layer, z);
744 return static_cast<Error>(err);
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800745}
746
747IComposer* HIDL_FETCH_IComposer(const char*)
748{
Chia-I Wue1768352016-12-19 12:56:54 +0800749 const hw_module_t* module = nullptr;
Chia-I Wu7f8d3962016-09-28 21:04:23 +0800750 int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &module);
751 if (err) {
752 ALOGE("failed to get hwcomposer module");
753 return nullptr;
754 }
755
756 return new HwcHal(module);
757}
758
759} // namespace implementation
760} // namespace V2_1
761} // namespace composer
762} // namespace graphics
763} // namespace hardware
764} // namespace android