blob: 0114430b2445ca52bc6c43f78c295564876282b7 [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
196BufferClone::BufferClone()
197 : mHandle(nullptr)
198{
199}
200
201BufferClone::BufferClone(BufferClone&& other)
202{
203 mHandle = other.mHandle;
204 other.mHandle = nullptr;
205}
206
207BufferClone& BufferClone::operator=(buffer_handle_t handle)
208{
209 clear();
210 mHandle = handle;
211 return *this;
212}
213
214BufferClone::~BufferClone()
215{
216 clear();
217}
218
219void BufferClone::clear()
220{
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,
748 slot, useCache, clientTarget);
749 if (err == Error::NONE) {
750 err = mHal.setClientTarget(mDisplay, clientTarget, fence,
751 dataspace, damage);
752 }
753 if (err != Error::NONE) {
754 close(fence);
755 mWriter.setError(getCommandLoc(), err);
756 }
757
758 return true;
759}
760
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500761bool ComposerClient::CommandReader::parseSetOutputBuffer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800762{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500763 if (length != CommandWriterBase::kSetOutputBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800764 return false;
765 }
766
Chia-I Wue1768352016-12-19 12:56:54 +0800767 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800768 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800769 auto outputBuffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800770 auto fence = readFence();
771
772 auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS,
773 slot, useCache, outputBuffer);
774 if (err == Error::NONE) {
775 err = mHal.setOutputBuffer(mDisplay, outputBuffer, fence);
776 }
777 if (err != Error::NONE) {
778 close(fence);
779 mWriter.setError(getCommandLoc(), err);
780 }
781
782 return true;
783}
784
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500785bool ComposerClient::CommandReader::parseValidateDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800786{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500787 if (length != CommandWriterBase::kValidateDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800788 return false;
789 }
790
791 std::vector<Layer> changedLayers;
792 std::vector<IComposerClient::Composition> compositionTypes;
Chia-I Wue1768352016-12-19 12:56:54 +0800793 uint32_t displayRequestMask = 0x0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800794 std::vector<Layer> requestedLayers;
795 std::vector<uint32_t> requestMasks;
796
Chia-I Wue1768352016-12-19 12:56:54 +0800797 auto err = mHal.validateDisplay(mDisplay, &changedLayers,
798 &compositionTypes, &displayRequestMask,
799 &requestedLayers, &requestMasks);
Chia-I Wubb61a722016-10-24 15:40:20 +0800800 if (err == Error::NONE) {
801 mWriter.setChangedCompositionTypes(changedLayers,
802 compositionTypes);
803 mWriter.setDisplayRequests(displayRequestMask,
804 requestedLayers, requestMasks);
805 } else {
806 mWriter.setError(getCommandLoc(), err);
807 }
808
809 return true;
810}
811
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500812bool ComposerClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800813{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500814 if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800815 return false;
816 }
817
818 auto err = mHal.acceptDisplayChanges(mDisplay);
819 if (err != Error::NONE) {
820 mWriter.setError(getCommandLoc(), err);
821 }
822
823 return true;
824}
825
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500826bool ComposerClient::CommandReader::parsePresentDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800827{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500828 if (length != CommandWriterBase::kPresentDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800829 return false;
830 }
831
Chia-I Wue1768352016-12-19 12:56:54 +0800832 int presentFence = -1;
Chia-I Wubb61a722016-10-24 15:40:20 +0800833 std::vector<Layer> layers;
834 std::vector<int> fences;
Chia-I Wue1768352016-12-19 12:56:54 +0800835 auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
Chia-I Wubb61a722016-10-24 15:40:20 +0800836 if (err == Error::NONE) {
837 mWriter.setPresentFence(presentFence);
838 mWriter.setReleaseFences(layers, fences);
839 } else {
840 mWriter.setError(getCommandLoc(), err);
841 }
842
843 return true;
844}
845
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500846bool ComposerClient::CommandReader::parseSetLayerCursorPosition(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800847{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500848 if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800849 return false;
850 }
851
852 auto err = mHal.setLayerCursorPosition(mDisplay, mLayer,
853 readSigned(), readSigned());
854 if (err != Error::NONE) {
855 mWriter.setError(getCommandLoc(), err);
856 }
857
858 return true;
859}
860
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500861bool ComposerClient::CommandReader::parseSetLayerBuffer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800862{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500863 if (length != CommandWriterBase::kSetLayerBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800864 return false;
865 }
866
Chia-I Wue1768352016-12-19 12:56:54 +0800867 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800868 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800869 auto buffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800870 auto fence = readFence();
871
872 auto err = lookupBuffer(BufferCache::LAYER_BUFFERS,
873 slot, useCache, buffer);
874 if (err == Error::NONE) {
875 err = mHal.setLayerBuffer(mDisplay, mLayer, buffer, fence);
876 }
877 if (err != Error::NONE) {
878 close(fence);
879 mWriter.setError(getCommandLoc(), err);
880 }
881
882 return true;
883}
884
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500885bool ComposerClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800886{
887 // N rectangles
888 if (length % 4 != 0) {
889 return false;
890 }
891
892 auto damage = readRegion(length / 4);
893 auto err = mHal.setLayerSurfaceDamage(mDisplay, mLayer, damage);
894 if (err != Error::NONE) {
895 mWriter.setError(getCommandLoc(), err);
896 }
897
898 return true;
899}
900
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500901bool ComposerClient::CommandReader::parseSetLayerBlendMode(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800902{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500903 if (length != CommandWriterBase::kSetLayerBlendModeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800904 return false;
905 }
906
907 auto err = mHal.setLayerBlendMode(mDisplay, mLayer, readSigned());
908 if (err != Error::NONE) {
909 mWriter.setError(getCommandLoc(), err);
910 }
911
912 return true;
913}
914
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500915bool ComposerClient::CommandReader::parseSetLayerColor(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800916{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500917 if (length != CommandWriterBase::kSetLayerColorLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800918 return false;
919 }
920
921 auto err = mHal.setLayerColor(mDisplay, mLayer, readColor());
922 if (err != Error::NONE) {
923 mWriter.setError(getCommandLoc(), err);
924 }
925
926 return true;
927}
928
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500929bool ComposerClient::CommandReader::parseSetLayerCompositionType(
930 uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800931{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500932 if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800933 return false;
934 }
935
936 auto err = mHal.setLayerCompositionType(mDisplay, mLayer, readSigned());
937 if (err != Error::NONE) {
938 mWriter.setError(getCommandLoc(), err);
939 }
940
941 return true;
942}
943
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500944bool ComposerClient::CommandReader::parseSetLayerDataspace(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800945{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500946 if (length != CommandWriterBase::kSetLayerDataspaceLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800947 return false;
948 }
949
950 auto err = mHal.setLayerDataspace(mDisplay, mLayer, readSigned());
951 if (err != Error::NONE) {
952 mWriter.setError(getCommandLoc(), err);
953 }
954
955 return true;
956}
957
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500958bool ComposerClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800959{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500960 if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800961 return false;
962 }
963
964 auto err = mHal.setLayerDisplayFrame(mDisplay, mLayer, readRect());
965 if (err != Error::NONE) {
966 mWriter.setError(getCommandLoc(), err);
967 }
968
969 return true;
970}
971
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500972bool ComposerClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800973{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500974 if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800975 return false;
976 }
977
Dan Stoza0df10c42016-12-19 15:22:47 -0800978 auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
Chia-I Wubb61a722016-10-24 15:40:20 +0800979 if (err != Error::NONE) {
980 mWriter.setError(getCommandLoc(), err);
981 }
982
983 return true;
984}
985
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500986bool ComposerClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800987{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500988 if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800989 return false;
990 }
991
992 auto stream = readHandle();
993
994 auto err = lookupLayerSidebandStream(stream);
995 if (err == Error::NONE) {
996 err = mHal.setLayerSidebandStream(mDisplay, mLayer, stream);
997 }
998 if (err != Error::NONE) {
999 mWriter.setError(getCommandLoc(), err);
1000 }
1001
1002 return true;
1003}
1004
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001005bool ComposerClient::CommandReader::parseSetLayerSourceCrop(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +08001006{
Daniel Nicoarabd82b812017-01-17 11:15:26 -05001007 if (length != CommandWriterBase::kSetLayerSourceCropLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +08001008 return false;
1009 }
1010
1011 auto err = mHal.setLayerSourceCrop(mDisplay, mLayer, readFRect());
1012 if (err != Error::NONE) {
1013 mWriter.setError(getCommandLoc(), err);
1014 }
1015
1016 return true;
1017}
1018
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001019bool ComposerClient::CommandReader::parseSetLayerTransform(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +08001020{
Daniel Nicoarabd82b812017-01-17 11:15:26 -05001021 if (length != CommandWriterBase::kSetLayerTransformLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +08001022 return false;
1023 }
1024
1025 auto err = mHal.setLayerTransform(mDisplay, mLayer, readSigned());
1026 if (err != Error::NONE) {
1027 mWriter.setError(getCommandLoc(), err);
1028 }
1029
1030 return true;
1031}
1032
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001033bool ComposerClient::CommandReader::parseSetLayerVisibleRegion(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +08001034{
1035 // N rectangles
1036 if (length % 4 != 0) {
1037 return false;
1038 }
1039
1040 auto region = readRegion(length / 4);
1041 auto err = mHal.setLayerVisibleRegion(mDisplay, mLayer, region);
1042 if (err != Error::NONE) {
1043 mWriter.setError(getCommandLoc(), err);
1044 }
1045
1046 return true;
1047}
1048
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001049bool ComposerClient::CommandReader::parseSetLayerZOrder(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +08001050{
Daniel Nicoarabd82b812017-01-17 11:15:26 -05001051 if (length != CommandWriterBase::kSetLayerZOrderLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +08001052 return false;
1053 }
1054
1055 auto err = mHal.setLayerZOrder(mDisplay, mLayer, read());
1056 if (err != Error::NONE) {
1057 mWriter.setError(getCommandLoc(), err);
1058 }
1059
1060 return true;
1061}
1062
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001063hwc_rect_t ComposerClient::CommandReader::readRect()
Chia-I Wubb61a722016-10-24 15:40:20 +08001064{
1065 return hwc_rect_t{
1066 readSigned(),
1067 readSigned(),
1068 readSigned(),
1069 readSigned(),
1070 };
1071}
1072
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001073std::vector<hwc_rect_t> ComposerClient::CommandReader::readRegion(size_t count)
Chia-I Wubb61a722016-10-24 15:40:20 +08001074{
1075 std::vector<hwc_rect_t> region;
1076 region.reserve(count);
1077 while (count > 0) {
1078 region.emplace_back(readRect());
1079 count--;
1080 }
1081
1082 return region;
1083}
1084
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001085hwc_frect_t ComposerClient::CommandReader::readFRect()
Chia-I Wubb61a722016-10-24 15:40:20 +08001086{
1087 return hwc_frect_t{
1088 readFloat(),
1089 readFloat(),
1090 readFloat(),
1091 readFloat(),
1092 };
1093}
1094
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001095Error ComposerClient::CommandReader::lookupBuffer(BufferCache cache,
1096 uint32_t slot, bool useCache, buffer_handle_t& handle)
Chia-I Wubb61a722016-10-24 15:40:20 +08001097{
1098 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1099
1100 auto dpy = mClient.mDisplayData.find(mDisplay);
1101 if (dpy == mClient.mDisplayData.end()) {
1102 return Error::BAD_DISPLAY;
1103 }
1104
1105 BufferClone* clone = nullptr;
1106 switch (cache) {
1107 case BufferCache::CLIENT_TARGETS:
1108 if (slot < dpy->second.ClientTargets.size()) {
1109 clone = &dpy->second.ClientTargets[slot];
1110 }
1111 break;
1112 case BufferCache::OUTPUT_BUFFERS:
1113 if (slot < dpy->second.OutputBuffers.size()) {
1114 clone = &dpy->second.OutputBuffers[slot];
1115 }
1116 break;
1117 case BufferCache::LAYER_BUFFERS:
1118 {
1119 auto ly = dpy->second.Layers.find(mLayer);
1120 if (ly == dpy->second.Layers.end()) {
1121 return Error::BAD_LAYER;
1122 }
1123 if (slot < ly->second.Buffers.size()) {
1124 clone = &ly->second.Buffers[slot];
1125 }
1126 }
1127 break;
1128 case BufferCache::LAYER_SIDEBAND_STREAMS:
1129 {
1130 auto ly = dpy->second.Layers.find(mLayer);
1131 if (ly == dpy->second.Layers.end()) {
1132 return Error::BAD_LAYER;
1133 }
1134 if (slot == 0) {
1135 clone = &ly->second.SidebandStream;
1136 }
1137 }
1138 break;
1139 default:
1140 break;
1141 }
1142
1143 if (!clone) {
1144 ALOGW("invalid buffer slot");
1145 return Error::BAD_PARAMETER;
1146 }
1147
1148 // use or update cache
1149 if (useCache) {
1150 handle = *clone;
1151 } else {
1152 if (!sHandleImporter.importBuffer(handle)) {
1153 return Error::NO_RESOURCES;
1154 }
1155
1156 *clone = handle;
1157 }
1158
1159 return Error::NONE;
1160}
1161
1162} // namespace implementation
1163} // namespace V2_1
1164} // namespace composer
1165} // namespace graphics
1166} // namespace hardware
1167} // namespace android