blob: a2d5d4bdd6ad9b791c0df5ce296876deda102183 [file] [log] [blame]
Chia-I Wubb61a722016-10-24 15:40:20 +08001/*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "HwcPassthrough"
18
19#include <hardware/gralloc.h>
20#include <hardware/gralloc1.h>
21#include <log/log.h>
22
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -050023#include "ComposerClient.h"
Chia-I Wubb61a722016-10-24 15:40:20 +080024#include "Hwc.h"
Chia-I Wubb61a722016-10-24 15:40:20 +080025#include "IComposerCommandBuffer.h"
26
27namespace android {
28namespace hardware {
29namespace graphics {
30namespace composer {
31namespace V2_1 {
32namespace implementation {
33
34namespace {
35
36class HandleImporter {
37public:
38 HandleImporter() : mInitialized(false) {}
39
40 bool initialize()
41 {
42 // allow only one client
43 if (mInitialized) {
44 return false;
45 }
46
47 if (!openGralloc()) {
48 return false;
49 }
50
51 mInitialized = true;
52 return true;
53 }
54
55 void cleanup()
56 {
57 if (!mInitialized) {
58 return;
59 }
60
61 closeGralloc();
62 mInitialized = false;
63 }
64
65 // In IComposer, any buffer_handle_t is owned by the caller and we need to
66 // make a clone for hwcomposer2. We also need to translate empty handle
67 // to nullptr. This function does that, in-place.
68 bool importBuffer(buffer_handle_t& handle)
69 {
70 if (!handle) {
71 return true;
72 }
73
74 if (!handle->numFds && !handle->numInts) {
75 handle = nullptr;
76 return true;
77 }
78
79 buffer_handle_t clone = cloneBuffer(handle);
80 if (!clone) {
81 return false;
82 }
83
84 handle = clone;
85 return true;
86 }
87
88 void freeBuffer(buffer_handle_t handle)
89 {
90 if (!handle) {
91 return;
92 }
93
94 releaseBuffer(handle);
95 }
96
97private:
98 bool mInitialized;
99
100 // Some existing gralloc drivers do not support retaining more than once,
101 // when we are in passthrough mode.
Chia-I Wubb61a722016-10-24 15:40:20 +0800102 bool openGralloc()
103 {
Chia-I Wue1768352016-12-19 12:56:54 +0800104 const hw_module_t* module = nullptr;
Chia-I Wubb61a722016-10-24 15:40:20 +0800105 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
106 if (err) {
107 ALOGE("failed to get gralloc module");
108 return false;
109 }
110
111 uint8_t major = (module->module_api_version >> 8) & 0xff;
112 if (major > 1) {
113 ALOGE("unknown gralloc module major version %d", major);
114 return false;
115 }
116
117 if (major == 1) {
118 err = gralloc1_open(module, &mDevice);
119 if (err) {
120 ALOGE("failed to open gralloc1 device");
121 return false;
122 }
123
124 mRetain = reinterpret_cast<GRALLOC1_PFN_RETAIN>(
125 mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RETAIN));
126 mRelease = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
127 mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RELEASE));
128 if (!mRetain || !mRelease) {
129 ALOGE("invalid gralloc1 device");
130 gralloc1_close(mDevice);
131 return false;
132 }
133 } else {
134 mModule = reinterpret_cast<const gralloc_module_t*>(module);
135 }
136
137 return true;
138 }
139
140 void closeGralloc()
141 {
142 if (mDevice) {
143 gralloc1_close(mDevice);
144 }
145 }
146
147 buffer_handle_t cloneBuffer(buffer_handle_t handle)
148 {
149 native_handle_t* clone = native_handle_clone(handle);
150 if (!clone) {
151 ALOGE("failed to clone buffer %p", handle);
152 return nullptr;
153 }
154
155 bool err;
156 if (mDevice) {
157 err = (mRetain(mDevice, clone) != GRALLOC1_ERROR_NONE);
158 } else {
159 err = (mModule->registerBuffer(mModule, clone) != 0);
160 }
161
162 if (err) {
163 ALOGE("failed to retain/register buffer %p", clone);
164 native_handle_close(clone);
165 native_handle_delete(clone);
166 return nullptr;
167 }
168
169 return clone;
170 }
171
172 void releaseBuffer(buffer_handle_t handle)
173 {
174 if (mDevice) {
175 mRelease(mDevice, handle);
176 } else {
177 mModule->unregisterBuffer(mModule, handle);
Chia-I Wubb61a722016-10-24 15:40:20 +0800178 }
Chia-I Wu939e4012016-12-12 21:51:33 +0800179 native_handle_close(handle);
180 native_handle_delete(const_cast<native_handle_t*>(handle));
Chia-I Wubb61a722016-10-24 15:40:20 +0800181 }
182
183 // gralloc1
184 gralloc1_device_t* mDevice;
185 GRALLOC1_PFN_RETAIN mRetain;
186 GRALLOC1_PFN_RELEASE mRelease;
187
188 // gralloc0
189 const gralloc_module_t* mModule;
Chia-I Wubb61a722016-10-24 15:40:20 +0800190};
191
192HandleImporter sHandleImporter;
193
194} // anonymous namespace
195
Chia-I Wu41a1c152017-03-09 15:41:59 -0800196BufferCacheEntry::BufferCacheEntry()
Chia-I Wubb61a722016-10-24 15:40:20 +0800197 : mHandle(nullptr)
198{
199}
200
Chia-I Wu41a1c152017-03-09 15:41:59 -0800201BufferCacheEntry::BufferCacheEntry(BufferCacheEntry&& other)
Chia-I Wubb61a722016-10-24 15:40:20 +0800202{
203 mHandle = other.mHandle;
204 other.mHandle = nullptr;
205}
206
Chia-I Wu41a1c152017-03-09 15:41:59 -0800207BufferCacheEntry& BufferCacheEntry::operator=(buffer_handle_t handle)
Chia-I Wubb61a722016-10-24 15:40:20 +0800208{
209 clear();
210 mHandle = handle;
211 return *this;
212}
213
Chia-I Wu41a1c152017-03-09 15:41:59 -0800214BufferCacheEntry::~BufferCacheEntry()
Chia-I Wubb61a722016-10-24 15:40:20 +0800215{
216 clear();
217}
218
Chia-I Wu41a1c152017-03-09 15:41:59 -0800219void BufferCacheEntry::clear()
Chia-I Wubb61a722016-10-24 15:40:20 +0800220{
221 if (mHandle) {
222 sHandleImporter.freeBuffer(mHandle);
223 }
224}
225
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500226ComposerClient::ComposerClient(ComposerBase& hal)
227 : mHal(hal), mWriter(kWriterInitialSize)
Chia-I Wubb61a722016-10-24 15:40:20 +0800228{
Chia-I Wubb61a722016-10-24 15:40:20 +0800229}
230
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500231ComposerClient::~ComposerClient()
Chia-I Wubb61a722016-10-24 15:40:20 +0800232{
Chia-I Wu6c84f7e2017-03-08 15:30:35 -0800233 // We want to call hwc2_close here (and move hwc2_open to the
234 // constructor), with the assumption that hwc2_close would
235 //
236 // - clean up all resources owned by the client
237 // - make sure all displays are blank (since there is no layer)
238 //
239 // But since SF used to crash at this point, different hwcomposer2
240 // implementations behave differently on hwc2_close. Our only portable
241 // choice really is to abort(). But that is not an option anymore
242 // because we might also have VTS or VR as clients that can come and go.
243 //
244 // Below we manually clean all resources (layers and virtual
245 // displays), and perform a presentDisplay afterwards.
246 ALOGW("destroying composer client");
Chia-I Wu43398712017-02-17 12:38:50 -0800247
Chia-I Wubb61a722016-10-24 15:40:20 +0800248 mHal.enableCallback(false);
Chia-I Wubb61a722016-10-24 15:40:20 +0800249
Chia-I Wu6c84f7e2017-03-08 15:30:35 -0800250 // no need to grab the mutex as any in-flight hwbinder call would have
251 // kept the client alive
Chia-I Wubb61a722016-10-24 15:40:20 +0800252 for (const auto& dpy : mDisplayData) {
Chia-I Wu6c84f7e2017-03-08 15:30:35 -0800253 ALOGW("destroying client resources for display %" PRIu64, dpy.first);
254
Chia-I Wubb61a722016-10-24 15:40:20 +0800255 for (const auto& ly : dpy.second.Layers) {
256 mHal.destroyLayer(dpy.first, ly.first);
257 }
258
259 if (dpy.second.IsVirtual) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800260 mHal.destroyVirtualDisplay(dpy.first);
Chia-I Wu6c84f7e2017-03-08 15:30:35 -0800261 } else {
262 ALOGW("performing a final presentDisplay");
263
264 std::vector<Layer> changedLayers;
265 std::vector<IComposerClient::Composition> compositionTypes;
266 uint32_t displayRequestMask = 0;
267 std::vector<Layer> requestedLayers;
268 std::vector<uint32_t> requestMasks;
269 mHal.validateDisplay(dpy.first, &changedLayers, &compositionTypes,
270 &displayRequestMask, &requestedLayers, &requestMasks);
271
272 mHal.acceptDisplayChanges(dpy.first);
273
274 int32_t presentFence = -1;
275 std::vector<Layer> releasedLayers;
276 std::vector<int32_t> releaseFences;
277 mHal.presentDisplay(dpy.first, &presentFence, &releasedLayers, &releaseFences);
278 if (presentFence >= 0) {
279 close(presentFence);
280 }
281 for (auto fence : releaseFences) {
282 if (fence >= 0) {
283 close(fence);
284 }
285 }
Chia-I Wubb61a722016-10-24 15:40:20 +0800286 }
287 }
288
289 mDisplayData.clear();
290
291 sHandleImporter.cleanup();
Chia-I Wu6c84f7e2017-03-08 15:30:35 -0800292
293 mHal.removeClient();
294
295 ALOGW("removed composer client");
Chia-I Wubb61a722016-10-24 15:40:20 +0800296}
297
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500298void ComposerClient::initialize()
299{
300 mReader = createCommandReader();
301 if (!sHandleImporter.initialize()) {
302 LOG_ALWAYS_FATAL("failed to initialize handle importer");
303 }
304}
305
306void ComposerClient::onHotplug(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800307 IComposerCallback::Connection connected)
308{
309 {
310 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
311
312 if (connected == IComposerCallback::Connection::CONNECTED) {
313 mDisplayData.emplace(display, DisplayData(false));
314 } else if (connected == IComposerCallback::Connection::DISCONNECTED) {
315 mDisplayData.erase(display);
316 }
317 }
318
Chia-I Wu43398712017-02-17 12:38:50 -0800319 auto ret = mCallback->onHotplug(display, connected);
320 ALOGE_IF(!ret.isOk(), "failed to send onHotplug: %s",
321 ret.description().c_str());
Chia-I Wubb61a722016-10-24 15:40:20 +0800322}
323
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500324void ComposerClient::onRefresh(Display display)
Chia-I Wubb61a722016-10-24 15:40:20 +0800325{
Chia-I Wu43398712017-02-17 12:38:50 -0800326 auto ret = mCallback->onRefresh(display);
327 ALOGE_IF(!ret.isOk(), "failed to send onRefresh: %s",
328 ret.description().c_str());
Chia-I Wubb61a722016-10-24 15:40:20 +0800329}
330
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500331void ComposerClient::onVsync(Display display, int64_t timestamp)
Chia-I Wubb61a722016-10-24 15:40:20 +0800332{
Chia-I Wu43398712017-02-17 12:38:50 -0800333 auto ret = mCallback->onVsync(display, timestamp);
334 ALOGE_IF(!ret.isOk(), "failed to send onVsync: %s",
335 ret.description().c_str());
Chia-I Wubb61a722016-10-24 15:40:20 +0800336}
337
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500338Return<void> ComposerClient::registerCallback(
339 const sp<IComposerCallback>& callback)
Chia-I Wubb61a722016-10-24 15:40:20 +0800340{
341 // no locking as we require this function to be called only once
342 mCallback = callback;
343 mHal.enableCallback(callback != nullptr);
344
345 return Void();
346}
347
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500348Return<uint32_t> ComposerClient::getMaxVirtualDisplayCount()
Chia-I Wubb61a722016-10-24 15:40:20 +0800349{
350 return mHal.getMaxVirtualDisplayCount();
351}
352
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500353Return<void> ComposerClient::createVirtualDisplay(uint32_t width,
354 uint32_t height, PixelFormat formatHint, uint32_t outputBufferSlotCount,
Chia-I Wubb61a722016-10-24 15:40:20 +0800355 createVirtualDisplay_cb hidl_cb)
356{
Chia-I Wue1768352016-12-19 12:56:54 +0800357 Display display = 0;
358 Error err = mHal.createVirtualDisplay(width, height,
359 &formatHint, &display);
Chia-I Wubb61a722016-10-24 15:40:20 +0800360 if (err == Error::NONE) {
361 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
362
363 auto dpy = mDisplayData.emplace(display, DisplayData(true)).first;
364 dpy->second.OutputBuffers.resize(outputBufferSlotCount);
365 }
366
367 hidl_cb(err, display, formatHint);
368 return Void();
369}
370
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500371Return<Error> ComposerClient::destroyVirtualDisplay(Display display)
Chia-I Wubb61a722016-10-24 15:40:20 +0800372{
373 Error err = mHal.destroyVirtualDisplay(display);
374 if (err == Error::NONE) {
375 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
376
377 mDisplayData.erase(display);
378 }
379
380 return err;
381}
382
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500383Return<void> ComposerClient::createLayer(Display display,
384 uint32_t bufferSlotCount, createLayer_cb hidl_cb)
Chia-I Wubb61a722016-10-24 15:40:20 +0800385{
Chia-I Wue1768352016-12-19 12:56:54 +0800386 Layer layer = 0;
387 Error err = mHal.createLayer(display, &layer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800388 if (err == Error::NONE) {
389 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
390
391 auto dpy = mDisplayData.find(display);
392 auto ly = dpy->second.Layers.emplace(layer, LayerBuffers()).first;
393 ly->second.Buffers.resize(bufferSlotCount);
394 }
395
396 hidl_cb(err, layer);
397 return Void();
398}
399
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500400Return<Error> ComposerClient::destroyLayer(Display display, Layer layer)
Chia-I Wubb61a722016-10-24 15:40:20 +0800401{
402 Error err = mHal.destroyLayer(display, layer);
403 if (err == Error::NONE) {
404 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
405
406 auto dpy = mDisplayData.find(display);
407 dpy->second.Layers.erase(layer);
408 }
409
410 return err;
411}
412
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500413Return<void> ComposerClient::getActiveConfig(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800414 getActiveConfig_cb hidl_cb)
415{
Chia-I Wue1768352016-12-19 12:56:54 +0800416 Config config = 0;
417 Error err = mHal.getActiveConfig(display, &config);
Chia-I Wubb61a722016-10-24 15:40:20 +0800418
419 hidl_cb(err, config);
420 return Void();
421}
422
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500423Return<Error> ComposerClient::getClientTargetSupport(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800424 uint32_t width, uint32_t height,
425 PixelFormat format, Dataspace dataspace)
426{
427 Error err = mHal.getClientTargetSupport(display,
428 width, height, format, dataspace);
429 return err;
430}
431
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500432Return<void> ComposerClient::getColorModes(Display display,
433 getColorModes_cb hidl_cb)
Chia-I Wubb61a722016-10-24 15:40:20 +0800434{
435 hidl_vec<ColorMode> modes;
Chia-I Wue1768352016-12-19 12:56:54 +0800436 Error err = mHal.getColorModes(display, &modes);
Chia-I Wubb61a722016-10-24 15:40:20 +0800437
438 hidl_cb(err, modes);
439 return Void();
440}
441
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500442Return<void> ComposerClient::getDisplayAttribute(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800443 Config config, Attribute attribute,
444 getDisplayAttribute_cb hidl_cb)
445{
Chia-I Wue1768352016-12-19 12:56:54 +0800446 int32_t value = 0;
447 Error err = mHal.getDisplayAttribute(display, config, attribute, &value);
Chia-I Wubb61a722016-10-24 15:40:20 +0800448
449 hidl_cb(err, value);
450 return Void();
451}
452
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500453Return<void> ComposerClient::getDisplayConfigs(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800454 getDisplayConfigs_cb hidl_cb)
455{
456 hidl_vec<Config> configs;
Chia-I Wue1768352016-12-19 12:56:54 +0800457 Error err = mHal.getDisplayConfigs(display, &configs);
Chia-I Wubb61a722016-10-24 15:40:20 +0800458
459 hidl_cb(err, configs);
460 return Void();
461}
462
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500463Return<void> ComposerClient::getDisplayName(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800464 getDisplayName_cb hidl_cb)
465{
466 hidl_string name;
Chia-I Wue1768352016-12-19 12:56:54 +0800467 Error err = mHal.getDisplayName(display, &name);
Chia-I Wubb61a722016-10-24 15:40:20 +0800468
469 hidl_cb(err, name);
470 return Void();
471}
472
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500473Return<void> ComposerClient::getDisplayType(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800474 getDisplayType_cb hidl_cb)
475{
Chia-I Wue1768352016-12-19 12:56:54 +0800476 DisplayType type = DisplayType::INVALID;
477 Error err = mHal.getDisplayType(display, &type);
Chia-I Wubb61a722016-10-24 15:40:20 +0800478
479 hidl_cb(err, type);
480 return Void();
481}
482
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500483Return<void> ComposerClient::getDozeSupport(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800484 getDozeSupport_cb hidl_cb)
485{
Chia-I Wue1768352016-12-19 12:56:54 +0800486 bool support = false;
487 Error err = mHal.getDozeSupport(display, &support);
Chia-I Wubb61a722016-10-24 15:40:20 +0800488
489 hidl_cb(err, support);
490 return Void();
491}
492
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500493Return<void> ComposerClient::getHdrCapabilities(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800494 getHdrCapabilities_cb hidl_cb)
495{
496 hidl_vec<Hdr> types;
497 float max_lumi = 0.0f;
498 float max_avg_lumi = 0.0f;
499 float min_lumi = 0.0f;
Chia-I Wue1768352016-12-19 12:56:54 +0800500 Error err = mHal.getHdrCapabilities(display, &types,
501 &max_lumi, &max_avg_lumi, &min_lumi);
Chia-I Wubb61a722016-10-24 15:40:20 +0800502
503 hidl_cb(err, types, max_lumi, max_avg_lumi, min_lumi);
504 return Void();
505}
506
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500507Return<Error> ComposerClient::setClientTargetSlotCount(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800508 uint32_t clientTargetSlotCount)
509{
510 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
511
512 auto dpy = mDisplayData.find(display);
513 if (dpy == mDisplayData.end()) {
514 return Error::BAD_DISPLAY;
515 }
516
517 dpy->second.ClientTargets.resize(clientTargetSlotCount);
518
519 return Error::NONE;
520}
521
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500522Return<Error> ComposerClient::setActiveConfig(Display display, Config config)
Chia-I Wubb61a722016-10-24 15:40:20 +0800523{
524 Error err = mHal.setActiveConfig(display, config);
525 return err;
526}
527
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500528Return<Error> ComposerClient::setColorMode(Display display, ColorMode mode)
Chia-I Wubb61a722016-10-24 15:40:20 +0800529{
530 Error err = mHal.setColorMode(display, mode);
531 return err;
532}
533
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500534Return<Error> ComposerClient::setPowerMode(Display display, PowerMode mode)
Chia-I Wubb61a722016-10-24 15:40:20 +0800535{
536 Error err = mHal.setPowerMode(display, mode);
537 return err;
538}
539
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500540Return<Error> ComposerClient::setVsyncEnabled(Display display, Vsync enabled)
Chia-I Wubb61a722016-10-24 15:40:20 +0800541{
542 Error err = mHal.setVsyncEnabled(display, enabled);
543 return err;
544}
545
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500546Return<Error> ComposerClient::setInputCommandQueue(
Hridya Valsaraju33351da2016-12-27 12:40:01 -0800547 const MQDescriptorSync<uint32_t>& descriptor)
Chia-I Wubb61a722016-10-24 15:40:20 +0800548{
549 std::lock_guard<std::mutex> lock(mCommandMutex);
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500550 return mReader->setMQDescriptor(descriptor) ?
Chia-I Wubb61a722016-10-24 15:40:20 +0800551 Error::NONE : Error::NO_RESOURCES;
552}
553
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500554Return<void> ComposerClient::getOutputCommandQueue(
Chia-I Wubb61a722016-10-24 15:40:20 +0800555 getOutputCommandQueue_cb hidl_cb)
556{
557 // no locking as we require this function to be called inside
558 // executeCommands_cb
559
560 auto outDescriptor = mWriter.getMQDescriptor();
561 if (outDescriptor) {
562 hidl_cb(Error::NONE, *outDescriptor);
563 } else {
Hridya Valsaraju790db102017-01-10 08:58:23 -0800564 hidl_cb(Error::NO_RESOURCES, CommandQueueType::Descriptor());
Chia-I Wubb61a722016-10-24 15:40:20 +0800565 }
566
567 return Void();
568}
569
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500570Return<void> ComposerClient::executeCommands(uint32_t inLength,
Chia-I Wubb61a722016-10-24 15:40:20 +0800571 const hidl_vec<hidl_handle>& inHandles,
572 executeCommands_cb hidl_cb)
573{
574 std::lock_guard<std::mutex> lock(mCommandMutex);
575
576 bool outChanged = false;
577 uint32_t outLength = 0;
578 hidl_vec<hidl_handle> outHandles;
579
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500580 if (!mReader->readQueue(inLength, inHandles)) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800581 hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
582 return Void();
583 }
584
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500585 Error err = mReader->parse();
Chia-I Wubb61a722016-10-24 15:40:20 +0800586 if (err == Error::NONE &&
Chia-I Wue1768352016-12-19 12:56:54 +0800587 !mWriter.writeQueue(&outChanged, &outLength, &outHandles)) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800588 err = Error::NO_RESOURCES;
589 }
590
591 hidl_cb(err, outChanged, outLength, outHandles);
592
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500593 mReader->reset();
Chia-I Wubb61a722016-10-24 15:40:20 +0800594 mWriter.reset();
595
596 return Void();
597}
598
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500599std::unique_ptr<ComposerClient::CommandReader>
600ComposerClient::createCommandReader()
601{
602 return std::unique_ptr<ComposerClient::CommandReader>(
603 new CommandReader(*this));
604}
605
606ComposerClient::CommandReader::CommandReader(ComposerClient& client)
Chia-I Wubb61a722016-10-24 15:40:20 +0800607 : mClient(client), mHal(client.mHal), mWriter(client.mWriter)
608{
609}
610
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500611ComposerClient::CommandReader::~CommandReader()
612{
613}
614
615Error ComposerClient::CommandReader::parse()
Chia-I Wubb61a722016-10-24 15:40:20 +0800616{
617 IComposerClient::Command command;
Chia-I Wue1768352016-12-19 12:56:54 +0800618 uint16_t length = 0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800619
620 while (!isEmpty()) {
Chia-I Wue1768352016-12-19 12:56:54 +0800621 if (!beginCommand(&command, &length)) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800622 break;
623 }
624
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500625 bool parsed = parseCommand(command, length);
Chia-I Wubb61a722016-10-24 15:40:20 +0800626 endCommand();
627
628 if (!parsed) {
629 ALOGE("failed to parse command 0x%x, length %" PRIu16,
630 command, length);
631 break;
632 }
633 }
634
635 return (isEmpty()) ? Error::NONE : Error::BAD_PARAMETER;
636}
637
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500638bool ComposerClient::CommandReader::parseCommand(
639 IComposerClient::Command command, uint16_t length) {
640 switch (command) {
641 case IComposerClient::Command::SELECT_DISPLAY:
642 return parseSelectDisplay(length);
643 case IComposerClient::Command::SELECT_LAYER:
644 return parseSelectLayer(length);
645 case IComposerClient::Command::SET_COLOR_TRANSFORM:
646 return parseSetColorTransform(length);
647 case IComposerClient::Command::SET_CLIENT_TARGET:
648 return parseSetClientTarget(length);
649 case IComposerClient::Command::SET_OUTPUT_BUFFER:
650 return parseSetOutputBuffer(length);
651 case IComposerClient::Command::VALIDATE_DISPLAY:
652 return parseValidateDisplay(length);
653 case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
654 return parseAcceptDisplayChanges(length);
655 case IComposerClient::Command::PRESENT_DISPLAY:
656 return parsePresentDisplay(length);
657 case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
658 return parseSetLayerCursorPosition(length);
659 case IComposerClient::Command::SET_LAYER_BUFFER:
660 return parseSetLayerBuffer(length);
661 case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
662 return parseSetLayerSurfaceDamage(length);
663 case IComposerClient::Command::SET_LAYER_BLEND_MODE:
664 return parseSetLayerBlendMode(length);
665 case IComposerClient::Command::SET_LAYER_COLOR:
666 return parseSetLayerColor(length);
667 case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
668 return parseSetLayerCompositionType(length);
669 case IComposerClient::Command::SET_LAYER_DATASPACE:
670 return parseSetLayerDataspace(length);
671 case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
672 return parseSetLayerDisplayFrame(length);
673 case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
674 return parseSetLayerPlaneAlpha(length);
675 case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
676 return parseSetLayerSidebandStream(length);
677 case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
678 return parseSetLayerSourceCrop(length);
679 case IComposerClient::Command::SET_LAYER_TRANSFORM:
680 return parseSetLayerTransform(length);
681 case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
682 return parseSetLayerVisibleRegion(length);
683 case IComposerClient::Command::SET_LAYER_Z_ORDER:
684 return parseSetLayerZOrder(length);
685 default:
686 return false;
687 }
688}
689
690bool ComposerClient::CommandReader::parseSelectDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800691{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500692 if (length != CommandWriterBase::kSelectDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800693 return false;
694 }
695
696 mDisplay = read64();
697 mWriter.selectDisplay(mDisplay);
698
699 return true;
700}
701
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500702bool ComposerClient::CommandReader::parseSelectLayer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800703{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500704 if (length != CommandWriterBase::kSelectLayerLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800705 return false;
706 }
707
708 mLayer = read64();
709
710 return true;
711}
712
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500713bool ComposerClient::CommandReader::parseSetColorTransform(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800714{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500715 if (length != CommandWriterBase::kSetColorTransformLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800716 return false;
717 }
718
719 float matrix[16];
720 for (int i = 0; i < 16; i++) {
721 matrix[i] = readFloat();
722 }
723 auto transform = readSigned();
724
725 auto err = mHal.setColorTransform(mDisplay, matrix, transform);
726 if (err != Error::NONE) {
727 mWriter.setError(getCommandLoc(), err);
728 }
729
730 return true;
731}
732
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500733bool ComposerClient::CommandReader::parseSetClientTarget(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800734{
735 // 4 parameters followed by N rectangles
736 if ((length - 4) % 4 != 0) {
737 return false;
738 }
739
Chia-I Wue1768352016-12-19 12:56:54 +0800740 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800741 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800742 auto clientTarget = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800743 auto fence = readFence();
744 auto dataspace = readSigned();
745 auto damage = readRegion((length - 4) / 4);
746
747 auto err = lookupBuffer(BufferCache::CLIENT_TARGETS,
Chia-I Wu41a1c152017-03-09 15:41:59 -0800748 slot, useCache, clientTarget, &clientTarget);
Chia-I Wubb61a722016-10-24 15:40:20 +0800749 if (err == Error::NONE) {
750 err = mHal.setClientTarget(mDisplay, clientTarget, fence,
751 dataspace, damage);
Chia-I Wu41a1c152017-03-09 15:41:59 -0800752
753 updateBuffer(BufferCache::CLIENT_TARGETS, slot, useCache,
754 clientTarget);
Chia-I Wubb61a722016-10-24 15:40:20 +0800755 }
756 if (err != Error::NONE) {
757 close(fence);
758 mWriter.setError(getCommandLoc(), err);
759 }
760
761 return true;
762}
763
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500764bool ComposerClient::CommandReader::parseSetOutputBuffer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800765{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500766 if (length != CommandWriterBase::kSetOutputBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800767 return false;
768 }
769
Chia-I Wue1768352016-12-19 12:56:54 +0800770 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800771 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800772 auto outputBuffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800773 auto fence = readFence();
774
775 auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS,
Chia-I Wu41a1c152017-03-09 15:41:59 -0800776 slot, useCache, outputBuffer, &outputBuffer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800777 if (err == Error::NONE) {
778 err = mHal.setOutputBuffer(mDisplay, outputBuffer, fence);
Chia-I Wu41a1c152017-03-09 15:41:59 -0800779
780 updateBuffer(BufferCache::OUTPUT_BUFFERS,
781 slot, useCache, outputBuffer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800782 }
783 if (err != Error::NONE) {
784 close(fence);
785 mWriter.setError(getCommandLoc(), err);
786 }
787
788 return true;
789}
790
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500791bool ComposerClient::CommandReader::parseValidateDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800792{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500793 if (length != CommandWriterBase::kValidateDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800794 return false;
795 }
796
797 std::vector<Layer> changedLayers;
798 std::vector<IComposerClient::Composition> compositionTypes;
Chia-I Wue1768352016-12-19 12:56:54 +0800799 uint32_t displayRequestMask = 0x0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800800 std::vector<Layer> requestedLayers;
801 std::vector<uint32_t> requestMasks;
802
Chia-I Wue1768352016-12-19 12:56:54 +0800803 auto err = mHal.validateDisplay(mDisplay, &changedLayers,
804 &compositionTypes, &displayRequestMask,
805 &requestedLayers, &requestMasks);
Chia-I Wubb61a722016-10-24 15:40:20 +0800806 if (err == Error::NONE) {
807 mWriter.setChangedCompositionTypes(changedLayers,
808 compositionTypes);
809 mWriter.setDisplayRequests(displayRequestMask,
810 requestedLayers, requestMasks);
811 } else {
812 mWriter.setError(getCommandLoc(), err);
813 }
814
815 return true;
816}
817
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500818bool ComposerClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800819{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500820 if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800821 return false;
822 }
823
824 auto err = mHal.acceptDisplayChanges(mDisplay);
825 if (err != Error::NONE) {
826 mWriter.setError(getCommandLoc(), err);
827 }
828
829 return true;
830}
831
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500832bool ComposerClient::CommandReader::parsePresentDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800833{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500834 if (length != CommandWriterBase::kPresentDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800835 return false;
836 }
837
Chia-I Wue1768352016-12-19 12:56:54 +0800838 int presentFence = -1;
Chia-I Wubb61a722016-10-24 15:40:20 +0800839 std::vector<Layer> layers;
840 std::vector<int> fences;
Chia-I Wue1768352016-12-19 12:56:54 +0800841 auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
Chia-I Wubb61a722016-10-24 15:40:20 +0800842 if (err == Error::NONE) {
843 mWriter.setPresentFence(presentFence);
844 mWriter.setReleaseFences(layers, fences);
845 } else {
846 mWriter.setError(getCommandLoc(), err);
847 }
848
849 return true;
850}
851
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500852bool ComposerClient::CommandReader::parseSetLayerCursorPosition(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800853{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500854 if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800855 return false;
856 }
857
858 auto err = mHal.setLayerCursorPosition(mDisplay, mLayer,
859 readSigned(), readSigned());
860 if (err != Error::NONE) {
861 mWriter.setError(getCommandLoc(), err);
862 }
863
864 return true;
865}
866
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500867bool ComposerClient::CommandReader::parseSetLayerBuffer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800868{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500869 if (length != CommandWriterBase::kSetLayerBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800870 return false;
871 }
872
Chia-I Wue1768352016-12-19 12:56:54 +0800873 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800874 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800875 auto buffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800876 auto fence = readFence();
877
878 auto err = lookupBuffer(BufferCache::LAYER_BUFFERS,
Chia-I Wu41a1c152017-03-09 15:41:59 -0800879 slot, useCache, buffer, &buffer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800880 if (err == Error::NONE) {
881 err = mHal.setLayerBuffer(mDisplay, mLayer, buffer, fence);
Chia-I Wu41a1c152017-03-09 15:41:59 -0800882
883 updateBuffer(BufferCache::LAYER_BUFFERS,
884 slot, useCache, buffer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800885 }
886 if (err != Error::NONE) {
887 close(fence);
888 mWriter.setError(getCommandLoc(), err);
889 }
890
891 return true;
892}
893
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500894bool ComposerClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800895{
896 // N rectangles
897 if (length % 4 != 0) {
898 return false;
899 }
900
901 auto damage = readRegion(length / 4);
902 auto err = mHal.setLayerSurfaceDamage(mDisplay, mLayer, damage);
903 if (err != Error::NONE) {
904 mWriter.setError(getCommandLoc(), err);
905 }
906
907 return true;
908}
909
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500910bool ComposerClient::CommandReader::parseSetLayerBlendMode(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800911{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500912 if (length != CommandWriterBase::kSetLayerBlendModeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800913 return false;
914 }
915
916 auto err = mHal.setLayerBlendMode(mDisplay, mLayer, readSigned());
917 if (err != Error::NONE) {
918 mWriter.setError(getCommandLoc(), err);
919 }
920
921 return true;
922}
923
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500924bool ComposerClient::CommandReader::parseSetLayerColor(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800925{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500926 if (length != CommandWriterBase::kSetLayerColorLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800927 return false;
928 }
929
930 auto err = mHal.setLayerColor(mDisplay, mLayer, readColor());
931 if (err != Error::NONE) {
932 mWriter.setError(getCommandLoc(), err);
933 }
934
935 return true;
936}
937
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500938bool ComposerClient::CommandReader::parseSetLayerCompositionType(
939 uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800940{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500941 if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800942 return false;
943 }
944
945 auto err = mHal.setLayerCompositionType(mDisplay, mLayer, readSigned());
946 if (err != Error::NONE) {
947 mWriter.setError(getCommandLoc(), err);
948 }
949
950 return true;
951}
952
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500953bool ComposerClient::CommandReader::parseSetLayerDataspace(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800954{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500955 if (length != CommandWriterBase::kSetLayerDataspaceLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800956 return false;
957 }
958
959 auto err = mHal.setLayerDataspace(mDisplay, mLayer, readSigned());
960 if (err != Error::NONE) {
961 mWriter.setError(getCommandLoc(), err);
962 }
963
964 return true;
965}
966
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500967bool ComposerClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800968{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500969 if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800970 return false;
971 }
972
973 auto err = mHal.setLayerDisplayFrame(mDisplay, mLayer, readRect());
974 if (err != Error::NONE) {
975 mWriter.setError(getCommandLoc(), err);
976 }
977
978 return true;
979}
980
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500981bool ComposerClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800982{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500983 if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800984 return false;
985 }
986
Dan Stoza0df10c42016-12-19 15:22:47 -0800987 auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
Chia-I Wubb61a722016-10-24 15:40:20 +0800988 if (err != Error::NONE) {
989 mWriter.setError(getCommandLoc(), err);
990 }
991
992 return true;
993}
994
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500995bool ComposerClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800996{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500997 if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800998 return false;
999 }
1000
1001 auto stream = readHandle();
1002
Chia-I Wu41a1c152017-03-09 15:41:59 -08001003 auto err = lookupLayerSidebandStream(stream, &stream);
Chia-I Wubb61a722016-10-24 15:40:20 +08001004 if (err == Error::NONE) {
1005 err = mHal.setLayerSidebandStream(mDisplay, mLayer, stream);
Chia-I Wu41a1c152017-03-09 15:41:59 -08001006
1007 updateLayerSidebandStream(stream);
Chia-I Wubb61a722016-10-24 15:40:20 +08001008 }
1009 if (err != Error::NONE) {
1010 mWriter.setError(getCommandLoc(), err);
1011 }
1012
1013 return true;
1014}
1015
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001016bool ComposerClient::CommandReader::parseSetLayerSourceCrop(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +08001017{
Daniel Nicoarabd82b812017-01-17 11:15:26 -05001018 if (length != CommandWriterBase::kSetLayerSourceCropLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +08001019 return false;
1020 }
1021
1022 auto err = mHal.setLayerSourceCrop(mDisplay, mLayer, readFRect());
1023 if (err != Error::NONE) {
1024 mWriter.setError(getCommandLoc(), err);
1025 }
1026
1027 return true;
1028}
1029
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001030bool ComposerClient::CommandReader::parseSetLayerTransform(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +08001031{
Daniel Nicoarabd82b812017-01-17 11:15:26 -05001032 if (length != CommandWriterBase::kSetLayerTransformLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +08001033 return false;
1034 }
1035
1036 auto err = mHal.setLayerTransform(mDisplay, mLayer, readSigned());
1037 if (err != Error::NONE) {
1038 mWriter.setError(getCommandLoc(), err);
1039 }
1040
1041 return true;
1042}
1043
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001044bool ComposerClient::CommandReader::parseSetLayerVisibleRegion(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +08001045{
1046 // N rectangles
1047 if (length % 4 != 0) {
1048 return false;
1049 }
1050
1051 auto region = readRegion(length / 4);
1052 auto err = mHal.setLayerVisibleRegion(mDisplay, mLayer, region);
1053 if (err != Error::NONE) {
1054 mWriter.setError(getCommandLoc(), err);
1055 }
1056
1057 return true;
1058}
1059
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001060bool ComposerClient::CommandReader::parseSetLayerZOrder(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +08001061{
Daniel Nicoarabd82b812017-01-17 11:15:26 -05001062 if (length != CommandWriterBase::kSetLayerZOrderLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +08001063 return false;
1064 }
1065
1066 auto err = mHal.setLayerZOrder(mDisplay, mLayer, read());
1067 if (err != Error::NONE) {
1068 mWriter.setError(getCommandLoc(), err);
1069 }
1070
1071 return true;
1072}
1073
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001074hwc_rect_t ComposerClient::CommandReader::readRect()
Chia-I Wubb61a722016-10-24 15:40:20 +08001075{
1076 return hwc_rect_t{
1077 readSigned(),
1078 readSigned(),
1079 readSigned(),
1080 readSigned(),
1081 };
1082}
1083
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001084std::vector<hwc_rect_t> ComposerClient::CommandReader::readRegion(size_t count)
Chia-I Wubb61a722016-10-24 15:40:20 +08001085{
1086 std::vector<hwc_rect_t> region;
1087 region.reserve(count);
1088 while (count > 0) {
1089 region.emplace_back(readRect());
1090 count--;
1091 }
1092
1093 return region;
1094}
1095
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001096hwc_frect_t ComposerClient::CommandReader::readFRect()
Chia-I Wubb61a722016-10-24 15:40:20 +08001097{
1098 return hwc_frect_t{
1099 readFloat(),
1100 readFloat(),
1101 readFloat(),
1102 readFloat(),
1103 };
1104}
1105
Chia-I Wu41a1c152017-03-09 15:41:59 -08001106Error ComposerClient::CommandReader::lookupBufferCacheEntryLocked(
1107 BufferCache cache, uint32_t slot, BufferCacheEntry** outEntry)
Chia-I Wubb61a722016-10-24 15:40:20 +08001108{
Chia-I Wubb61a722016-10-24 15:40:20 +08001109 auto dpy = mClient.mDisplayData.find(mDisplay);
1110 if (dpy == mClient.mDisplayData.end()) {
1111 return Error::BAD_DISPLAY;
1112 }
1113
Chia-I Wu41a1c152017-03-09 15:41:59 -08001114 BufferCacheEntry* entry = nullptr;
Chia-I Wubb61a722016-10-24 15:40:20 +08001115 switch (cache) {
1116 case BufferCache::CLIENT_TARGETS:
1117 if (slot < dpy->second.ClientTargets.size()) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001118 entry = &dpy->second.ClientTargets[slot];
Chia-I Wubb61a722016-10-24 15:40:20 +08001119 }
1120 break;
1121 case BufferCache::OUTPUT_BUFFERS:
1122 if (slot < dpy->second.OutputBuffers.size()) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001123 entry = &dpy->second.OutputBuffers[slot];
Chia-I Wubb61a722016-10-24 15:40:20 +08001124 }
1125 break;
1126 case BufferCache::LAYER_BUFFERS:
1127 {
1128 auto ly = dpy->second.Layers.find(mLayer);
1129 if (ly == dpy->second.Layers.end()) {
1130 return Error::BAD_LAYER;
1131 }
1132 if (slot < ly->second.Buffers.size()) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001133 entry = &ly->second.Buffers[slot];
Chia-I Wubb61a722016-10-24 15:40:20 +08001134 }
1135 }
1136 break;
1137 case BufferCache::LAYER_SIDEBAND_STREAMS:
1138 {
1139 auto ly = dpy->second.Layers.find(mLayer);
1140 if (ly == dpy->second.Layers.end()) {
1141 return Error::BAD_LAYER;
1142 }
1143 if (slot == 0) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001144 entry = &ly->second.SidebandStream;
Chia-I Wubb61a722016-10-24 15:40:20 +08001145 }
1146 }
1147 break;
1148 default:
1149 break;
1150 }
1151
Chia-I Wu41a1c152017-03-09 15:41:59 -08001152 if (!entry) {
1153 ALOGW("invalid buffer slot %" PRIu32, slot);
Chia-I Wubb61a722016-10-24 15:40:20 +08001154 return Error::BAD_PARAMETER;
1155 }
1156
Chia-I Wu41a1c152017-03-09 15:41:59 -08001157 *outEntry = entry;
1158
1159 return Error::NONE;
1160}
1161
1162Error ComposerClient::CommandReader::lookupBuffer(BufferCache cache,
1163 uint32_t slot, bool useCache, buffer_handle_t handle,
1164 buffer_handle_t* outHandle)
1165{
Chia-I Wubb61a722016-10-24 15:40:20 +08001166 if (useCache) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001167 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1168
1169 BufferCacheEntry* entry;
1170 Error error = lookupBufferCacheEntryLocked(cache, slot, &entry);
1171 if (error != Error::NONE) {
1172 return error;
1173 }
1174
1175 // input handle is ignored
1176 *outHandle = entry->getHandle();
Chia-I Wubb61a722016-10-24 15:40:20 +08001177 } else {
1178 if (!sHandleImporter.importBuffer(handle)) {
1179 return Error::NO_RESOURCES;
1180 }
1181
Chia-I Wu41a1c152017-03-09 15:41:59 -08001182 *outHandle = handle;
Chia-I Wubb61a722016-10-24 15:40:20 +08001183 }
1184
1185 return Error::NONE;
1186}
1187
Chia-I Wu41a1c152017-03-09 15:41:59 -08001188void ComposerClient::CommandReader::updateBuffer(BufferCache cache,
1189 uint32_t slot, bool useCache, buffer_handle_t handle)
1190{
1191 // handle was looked up from cache
1192 if (useCache) {
1193 return;
1194 }
1195
1196 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1197
1198 BufferCacheEntry* entry = nullptr;
1199 lookupBufferCacheEntryLocked(cache, slot, &entry);
1200 LOG_FATAL_IF(!entry, "failed to find the cache entry to update");
1201
1202 *entry = handle;
1203}
1204
Chia-I Wubb61a722016-10-24 15:40:20 +08001205} // namespace implementation
1206} // namespace V2_1
1207} // namespace composer
1208} // namespace graphics
1209} // namespace hardware
1210} // namespace android