blob: cd2f0493ad0329f0081d826f984b1e3ef1c04079 [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 Wu43398712017-02-17 12:38:50 -0800233 ALOGD("client destroyed");
234
Chia-I Wubb61a722016-10-24 15:40:20 +0800235 mHal.enableCallback(false);
236 mHal.removeClient();
237
238 // no need to grab the mutex as any in-flight hwbinder call should keep
239 // the client alive
240 for (const auto& dpy : mDisplayData) {
241 if (!dpy.second.Layers.empty()) {
242 ALOGW("client destroyed with valid layers");
243 }
244 for (const auto& ly : dpy.second.Layers) {
245 mHal.destroyLayer(dpy.first, ly.first);
246 }
247
248 if (dpy.second.IsVirtual) {
249 ALOGW("client destroyed with valid virtual display");
250 mHal.destroyVirtualDisplay(dpy.first);
251 }
252 }
253
254 mDisplayData.clear();
255
256 sHandleImporter.cleanup();
257}
258
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500259void ComposerClient::initialize()
260{
261 mReader = createCommandReader();
262 if (!sHandleImporter.initialize()) {
263 LOG_ALWAYS_FATAL("failed to initialize handle importer");
264 }
265}
266
267void ComposerClient::onHotplug(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800268 IComposerCallback::Connection connected)
269{
270 {
271 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
272
273 if (connected == IComposerCallback::Connection::CONNECTED) {
274 mDisplayData.emplace(display, DisplayData(false));
275 } else if (connected == IComposerCallback::Connection::DISCONNECTED) {
276 mDisplayData.erase(display);
277 }
278 }
279
Chia-I Wu43398712017-02-17 12:38:50 -0800280 auto ret = mCallback->onHotplug(display, connected);
281 ALOGE_IF(!ret.isOk(), "failed to send onHotplug: %s",
282 ret.description().c_str());
Chia-I Wubb61a722016-10-24 15:40:20 +0800283}
284
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500285void ComposerClient::onRefresh(Display display)
Chia-I Wubb61a722016-10-24 15:40:20 +0800286{
Chia-I Wu43398712017-02-17 12:38:50 -0800287 auto ret = mCallback->onRefresh(display);
288 ALOGE_IF(!ret.isOk(), "failed to send onRefresh: %s",
289 ret.description().c_str());
Chia-I Wubb61a722016-10-24 15:40:20 +0800290}
291
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500292void ComposerClient::onVsync(Display display, int64_t timestamp)
Chia-I Wubb61a722016-10-24 15:40:20 +0800293{
Chia-I Wu43398712017-02-17 12:38:50 -0800294 auto ret = mCallback->onVsync(display, timestamp);
295 ALOGE_IF(!ret.isOk(), "failed to send onVsync: %s",
296 ret.description().c_str());
Chia-I Wubb61a722016-10-24 15:40:20 +0800297}
298
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500299Return<void> ComposerClient::registerCallback(
300 const sp<IComposerCallback>& callback)
Chia-I Wubb61a722016-10-24 15:40:20 +0800301{
302 // no locking as we require this function to be called only once
303 mCallback = callback;
304 mHal.enableCallback(callback != nullptr);
305
306 return Void();
307}
308
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500309Return<uint32_t> ComposerClient::getMaxVirtualDisplayCount()
Chia-I Wubb61a722016-10-24 15:40:20 +0800310{
311 return mHal.getMaxVirtualDisplayCount();
312}
313
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500314Return<void> ComposerClient::createVirtualDisplay(uint32_t width,
315 uint32_t height, PixelFormat formatHint, uint32_t outputBufferSlotCount,
Chia-I Wubb61a722016-10-24 15:40:20 +0800316 createVirtualDisplay_cb hidl_cb)
317{
Chia-I Wue1768352016-12-19 12:56:54 +0800318 Display display = 0;
319 Error err = mHal.createVirtualDisplay(width, height,
320 &formatHint, &display);
Chia-I Wubb61a722016-10-24 15:40:20 +0800321 if (err == Error::NONE) {
322 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
323
324 auto dpy = mDisplayData.emplace(display, DisplayData(true)).first;
325 dpy->second.OutputBuffers.resize(outputBufferSlotCount);
326 }
327
328 hidl_cb(err, display, formatHint);
329 return Void();
330}
331
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500332Return<Error> ComposerClient::destroyVirtualDisplay(Display display)
Chia-I Wubb61a722016-10-24 15:40:20 +0800333{
334 Error err = mHal.destroyVirtualDisplay(display);
335 if (err == Error::NONE) {
336 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
337
338 mDisplayData.erase(display);
339 }
340
341 return err;
342}
343
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500344Return<void> ComposerClient::createLayer(Display display,
345 uint32_t bufferSlotCount, createLayer_cb hidl_cb)
Chia-I Wubb61a722016-10-24 15:40:20 +0800346{
Chia-I Wue1768352016-12-19 12:56:54 +0800347 Layer layer = 0;
348 Error err = mHal.createLayer(display, &layer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800349 if (err == Error::NONE) {
350 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
351
352 auto dpy = mDisplayData.find(display);
353 auto ly = dpy->second.Layers.emplace(layer, LayerBuffers()).first;
354 ly->second.Buffers.resize(bufferSlotCount);
355 }
356
357 hidl_cb(err, layer);
358 return Void();
359}
360
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500361Return<Error> ComposerClient::destroyLayer(Display display, Layer layer)
Chia-I Wubb61a722016-10-24 15:40:20 +0800362{
363 Error err = mHal.destroyLayer(display, layer);
364 if (err == Error::NONE) {
365 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
366
367 auto dpy = mDisplayData.find(display);
368 dpy->second.Layers.erase(layer);
369 }
370
371 return err;
372}
373
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500374Return<void> ComposerClient::getActiveConfig(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800375 getActiveConfig_cb hidl_cb)
376{
Chia-I Wue1768352016-12-19 12:56:54 +0800377 Config config = 0;
378 Error err = mHal.getActiveConfig(display, &config);
Chia-I Wubb61a722016-10-24 15:40:20 +0800379
380 hidl_cb(err, config);
381 return Void();
382}
383
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500384Return<Error> ComposerClient::getClientTargetSupport(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800385 uint32_t width, uint32_t height,
386 PixelFormat format, Dataspace dataspace)
387{
388 Error err = mHal.getClientTargetSupport(display,
389 width, height, format, dataspace);
390 return err;
391}
392
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500393Return<void> ComposerClient::getColorModes(Display display,
394 getColorModes_cb hidl_cb)
Chia-I Wubb61a722016-10-24 15:40:20 +0800395{
396 hidl_vec<ColorMode> modes;
Chia-I Wue1768352016-12-19 12:56:54 +0800397 Error err = mHal.getColorModes(display, &modes);
Chia-I Wubb61a722016-10-24 15:40:20 +0800398
399 hidl_cb(err, modes);
400 return Void();
401}
402
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500403Return<void> ComposerClient::getDisplayAttribute(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800404 Config config, Attribute attribute,
405 getDisplayAttribute_cb hidl_cb)
406{
Chia-I Wue1768352016-12-19 12:56:54 +0800407 int32_t value = 0;
408 Error err = mHal.getDisplayAttribute(display, config, attribute, &value);
Chia-I Wubb61a722016-10-24 15:40:20 +0800409
410 hidl_cb(err, value);
411 return Void();
412}
413
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500414Return<void> ComposerClient::getDisplayConfigs(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800415 getDisplayConfigs_cb hidl_cb)
416{
417 hidl_vec<Config> configs;
Chia-I Wue1768352016-12-19 12:56:54 +0800418 Error err = mHal.getDisplayConfigs(display, &configs);
Chia-I Wubb61a722016-10-24 15:40:20 +0800419
420 hidl_cb(err, configs);
421 return Void();
422}
423
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500424Return<void> ComposerClient::getDisplayName(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800425 getDisplayName_cb hidl_cb)
426{
427 hidl_string name;
Chia-I Wue1768352016-12-19 12:56:54 +0800428 Error err = mHal.getDisplayName(display, &name);
Chia-I Wubb61a722016-10-24 15:40:20 +0800429
430 hidl_cb(err, name);
431 return Void();
432}
433
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500434Return<void> ComposerClient::getDisplayType(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800435 getDisplayType_cb hidl_cb)
436{
Chia-I Wue1768352016-12-19 12:56:54 +0800437 DisplayType type = DisplayType::INVALID;
438 Error err = mHal.getDisplayType(display, &type);
Chia-I Wubb61a722016-10-24 15:40:20 +0800439
440 hidl_cb(err, type);
441 return Void();
442}
443
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500444Return<void> ComposerClient::getDozeSupport(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800445 getDozeSupport_cb hidl_cb)
446{
Chia-I Wue1768352016-12-19 12:56:54 +0800447 bool support = false;
448 Error err = mHal.getDozeSupport(display, &support);
Chia-I Wubb61a722016-10-24 15:40:20 +0800449
450 hidl_cb(err, support);
451 return Void();
452}
453
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500454Return<void> ComposerClient::getHdrCapabilities(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800455 getHdrCapabilities_cb hidl_cb)
456{
457 hidl_vec<Hdr> types;
458 float max_lumi = 0.0f;
459 float max_avg_lumi = 0.0f;
460 float min_lumi = 0.0f;
Chia-I Wue1768352016-12-19 12:56:54 +0800461 Error err = mHal.getHdrCapabilities(display, &types,
462 &max_lumi, &max_avg_lumi, &min_lumi);
Chia-I Wubb61a722016-10-24 15:40:20 +0800463
464 hidl_cb(err, types, max_lumi, max_avg_lumi, min_lumi);
465 return Void();
466}
467
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500468Return<Error> ComposerClient::setClientTargetSlotCount(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800469 uint32_t clientTargetSlotCount)
470{
471 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
472
473 auto dpy = mDisplayData.find(display);
474 if (dpy == mDisplayData.end()) {
475 return Error::BAD_DISPLAY;
476 }
477
478 dpy->second.ClientTargets.resize(clientTargetSlotCount);
479
480 return Error::NONE;
481}
482
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500483Return<Error> ComposerClient::setActiveConfig(Display display, Config config)
Chia-I Wubb61a722016-10-24 15:40:20 +0800484{
485 Error err = mHal.setActiveConfig(display, config);
486 return err;
487}
488
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500489Return<Error> ComposerClient::setColorMode(Display display, ColorMode mode)
Chia-I Wubb61a722016-10-24 15:40:20 +0800490{
491 Error err = mHal.setColorMode(display, mode);
492 return err;
493}
494
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500495Return<Error> ComposerClient::setPowerMode(Display display, PowerMode mode)
Chia-I Wubb61a722016-10-24 15:40:20 +0800496{
497 Error err = mHal.setPowerMode(display, mode);
498 return err;
499}
500
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500501Return<Error> ComposerClient::setVsyncEnabled(Display display, Vsync enabled)
Chia-I Wubb61a722016-10-24 15:40:20 +0800502{
503 Error err = mHal.setVsyncEnabled(display, enabled);
504 return err;
505}
506
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500507Return<Error> ComposerClient::setInputCommandQueue(
Hridya Valsaraju33351da2016-12-27 12:40:01 -0800508 const MQDescriptorSync<uint32_t>& descriptor)
Chia-I Wubb61a722016-10-24 15:40:20 +0800509{
510 std::lock_guard<std::mutex> lock(mCommandMutex);
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500511 return mReader->setMQDescriptor(descriptor) ?
Chia-I Wubb61a722016-10-24 15:40:20 +0800512 Error::NONE : Error::NO_RESOURCES;
513}
514
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500515Return<void> ComposerClient::getOutputCommandQueue(
Chia-I Wubb61a722016-10-24 15:40:20 +0800516 getOutputCommandQueue_cb hidl_cb)
517{
518 // no locking as we require this function to be called inside
519 // executeCommands_cb
520
521 auto outDescriptor = mWriter.getMQDescriptor();
522 if (outDescriptor) {
523 hidl_cb(Error::NONE, *outDescriptor);
524 } else {
Hridya Valsaraju790db102017-01-10 08:58:23 -0800525 hidl_cb(Error::NO_RESOURCES, CommandQueueType::Descriptor());
Chia-I Wubb61a722016-10-24 15:40:20 +0800526 }
527
528 return Void();
529}
530
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500531Return<void> ComposerClient::executeCommands(uint32_t inLength,
Chia-I Wubb61a722016-10-24 15:40:20 +0800532 const hidl_vec<hidl_handle>& inHandles,
533 executeCommands_cb hidl_cb)
534{
535 std::lock_guard<std::mutex> lock(mCommandMutex);
536
537 bool outChanged = false;
538 uint32_t outLength = 0;
539 hidl_vec<hidl_handle> outHandles;
540
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500541 if (!mReader->readQueue(inLength, inHandles)) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800542 hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
543 return Void();
544 }
545
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500546 Error err = mReader->parse();
Chia-I Wubb61a722016-10-24 15:40:20 +0800547 if (err == Error::NONE &&
Chia-I Wue1768352016-12-19 12:56:54 +0800548 !mWriter.writeQueue(&outChanged, &outLength, &outHandles)) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800549 err = Error::NO_RESOURCES;
550 }
551
552 hidl_cb(err, outChanged, outLength, outHandles);
553
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500554 mReader->reset();
Chia-I Wubb61a722016-10-24 15:40:20 +0800555 mWriter.reset();
556
557 return Void();
558}
559
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500560std::unique_ptr<ComposerClient::CommandReader>
561ComposerClient::createCommandReader()
562{
563 return std::unique_ptr<ComposerClient::CommandReader>(
564 new CommandReader(*this));
565}
566
567ComposerClient::CommandReader::CommandReader(ComposerClient& client)
Chia-I Wubb61a722016-10-24 15:40:20 +0800568 : mClient(client), mHal(client.mHal), mWriter(client.mWriter)
569{
570}
571
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500572ComposerClient::CommandReader::~CommandReader()
573{
574}
575
576Error ComposerClient::CommandReader::parse()
Chia-I Wubb61a722016-10-24 15:40:20 +0800577{
578 IComposerClient::Command command;
Chia-I Wue1768352016-12-19 12:56:54 +0800579 uint16_t length = 0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800580
581 while (!isEmpty()) {
Chia-I Wue1768352016-12-19 12:56:54 +0800582 if (!beginCommand(&command, &length)) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800583 break;
584 }
585
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500586 bool parsed = parseCommand(command, length);
Chia-I Wubb61a722016-10-24 15:40:20 +0800587 endCommand();
588
589 if (!parsed) {
590 ALOGE("failed to parse command 0x%x, length %" PRIu16,
591 command, length);
592 break;
593 }
594 }
595
596 return (isEmpty()) ? Error::NONE : Error::BAD_PARAMETER;
597}
598
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500599bool ComposerClient::CommandReader::parseCommand(
600 IComposerClient::Command command, uint16_t length) {
601 switch (command) {
602 case IComposerClient::Command::SELECT_DISPLAY:
603 return parseSelectDisplay(length);
604 case IComposerClient::Command::SELECT_LAYER:
605 return parseSelectLayer(length);
606 case IComposerClient::Command::SET_COLOR_TRANSFORM:
607 return parseSetColorTransform(length);
608 case IComposerClient::Command::SET_CLIENT_TARGET:
609 return parseSetClientTarget(length);
610 case IComposerClient::Command::SET_OUTPUT_BUFFER:
611 return parseSetOutputBuffer(length);
612 case IComposerClient::Command::VALIDATE_DISPLAY:
613 return parseValidateDisplay(length);
614 case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
615 return parseAcceptDisplayChanges(length);
616 case IComposerClient::Command::PRESENT_DISPLAY:
617 return parsePresentDisplay(length);
618 case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
619 return parseSetLayerCursorPosition(length);
620 case IComposerClient::Command::SET_LAYER_BUFFER:
621 return parseSetLayerBuffer(length);
622 case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
623 return parseSetLayerSurfaceDamage(length);
624 case IComposerClient::Command::SET_LAYER_BLEND_MODE:
625 return parseSetLayerBlendMode(length);
626 case IComposerClient::Command::SET_LAYER_COLOR:
627 return parseSetLayerColor(length);
628 case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
629 return parseSetLayerCompositionType(length);
630 case IComposerClient::Command::SET_LAYER_DATASPACE:
631 return parseSetLayerDataspace(length);
632 case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
633 return parseSetLayerDisplayFrame(length);
634 case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
635 return parseSetLayerPlaneAlpha(length);
636 case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
637 return parseSetLayerSidebandStream(length);
638 case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
639 return parseSetLayerSourceCrop(length);
640 case IComposerClient::Command::SET_LAYER_TRANSFORM:
641 return parseSetLayerTransform(length);
642 case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
643 return parseSetLayerVisibleRegion(length);
644 case IComposerClient::Command::SET_LAYER_Z_ORDER:
645 return parseSetLayerZOrder(length);
646 default:
647 return false;
648 }
649}
650
651bool ComposerClient::CommandReader::parseSelectDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800652{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500653 if (length != CommandWriterBase::kSelectDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800654 return false;
655 }
656
657 mDisplay = read64();
658 mWriter.selectDisplay(mDisplay);
659
660 return true;
661}
662
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500663bool ComposerClient::CommandReader::parseSelectLayer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800664{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500665 if (length != CommandWriterBase::kSelectLayerLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800666 return false;
667 }
668
669 mLayer = read64();
670
671 return true;
672}
673
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500674bool ComposerClient::CommandReader::parseSetColorTransform(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800675{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500676 if (length != CommandWriterBase::kSetColorTransformLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800677 return false;
678 }
679
680 float matrix[16];
681 for (int i = 0; i < 16; i++) {
682 matrix[i] = readFloat();
683 }
684 auto transform = readSigned();
685
686 auto err = mHal.setColorTransform(mDisplay, matrix, transform);
687 if (err != Error::NONE) {
688 mWriter.setError(getCommandLoc(), err);
689 }
690
691 return true;
692}
693
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500694bool ComposerClient::CommandReader::parseSetClientTarget(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800695{
696 // 4 parameters followed by N rectangles
697 if ((length - 4) % 4 != 0) {
698 return false;
699 }
700
Chia-I Wue1768352016-12-19 12:56:54 +0800701 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800702 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800703 auto clientTarget = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800704 auto fence = readFence();
705 auto dataspace = readSigned();
706 auto damage = readRegion((length - 4) / 4);
707
708 auto err = lookupBuffer(BufferCache::CLIENT_TARGETS,
Chia-I Wu41a1c152017-03-09 15:41:59 -0800709 slot, useCache, clientTarget, &clientTarget);
Chia-I Wubb61a722016-10-24 15:40:20 +0800710 if (err == Error::NONE) {
711 err = mHal.setClientTarget(mDisplay, clientTarget, fence,
712 dataspace, damage);
Chia-I Wu41a1c152017-03-09 15:41:59 -0800713
714 updateBuffer(BufferCache::CLIENT_TARGETS, slot, useCache,
715 clientTarget);
Chia-I Wubb61a722016-10-24 15:40:20 +0800716 }
717 if (err != Error::NONE) {
718 close(fence);
719 mWriter.setError(getCommandLoc(), err);
720 }
721
722 return true;
723}
724
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500725bool ComposerClient::CommandReader::parseSetOutputBuffer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800726{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500727 if (length != CommandWriterBase::kSetOutputBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800728 return false;
729 }
730
Chia-I Wue1768352016-12-19 12:56:54 +0800731 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800732 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800733 auto outputBuffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800734 auto fence = readFence();
735
736 auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS,
Chia-I Wu41a1c152017-03-09 15:41:59 -0800737 slot, useCache, outputBuffer, &outputBuffer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800738 if (err == Error::NONE) {
739 err = mHal.setOutputBuffer(mDisplay, outputBuffer, fence);
Chia-I Wu41a1c152017-03-09 15:41:59 -0800740
741 updateBuffer(BufferCache::OUTPUT_BUFFERS,
742 slot, useCache, outputBuffer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800743 }
744 if (err != Error::NONE) {
745 close(fence);
746 mWriter.setError(getCommandLoc(), err);
747 }
748
749 return true;
750}
751
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500752bool ComposerClient::CommandReader::parseValidateDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800753{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500754 if (length != CommandWriterBase::kValidateDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800755 return false;
756 }
757
758 std::vector<Layer> changedLayers;
759 std::vector<IComposerClient::Composition> compositionTypes;
Chia-I Wue1768352016-12-19 12:56:54 +0800760 uint32_t displayRequestMask = 0x0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800761 std::vector<Layer> requestedLayers;
762 std::vector<uint32_t> requestMasks;
763
Chia-I Wue1768352016-12-19 12:56:54 +0800764 auto err = mHal.validateDisplay(mDisplay, &changedLayers,
765 &compositionTypes, &displayRequestMask,
766 &requestedLayers, &requestMasks);
Chia-I Wubb61a722016-10-24 15:40:20 +0800767 if (err == Error::NONE) {
768 mWriter.setChangedCompositionTypes(changedLayers,
769 compositionTypes);
770 mWriter.setDisplayRequests(displayRequestMask,
771 requestedLayers, requestMasks);
772 } else {
773 mWriter.setError(getCommandLoc(), err);
774 }
775
776 return true;
777}
778
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500779bool ComposerClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800780{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500781 if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800782 return false;
783 }
784
785 auto err = mHal.acceptDisplayChanges(mDisplay);
786 if (err != Error::NONE) {
787 mWriter.setError(getCommandLoc(), err);
788 }
789
790 return true;
791}
792
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500793bool ComposerClient::CommandReader::parsePresentDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800794{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500795 if (length != CommandWriterBase::kPresentDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800796 return false;
797 }
798
Chia-I Wue1768352016-12-19 12:56:54 +0800799 int presentFence = -1;
Chia-I Wubb61a722016-10-24 15:40:20 +0800800 std::vector<Layer> layers;
801 std::vector<int> fences;
Chia-I Wue1768352016-12-19 12:56:54 +0800802 auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
Chia-I Wubb61a722016-10-24 15:40:20 +0800803 if (err == Error::NONE) {
804 mWriter.setPresentFence(presentFence);
805 mWriter.setReleaseFences(layers, fences);
806 } else {
807 mWriter.setError(getCommandLoc(), err);
808 }
809
810 return true;
811}
812
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500813bool ComposerClient::CommandReader::parseSetLayerCursorPosition(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800814{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500815 if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800816 return false;
817 }
818
819 auto err = mHal.setLayerCursorPosition(mDisplay, mLayer,
820 readSigned(), readSigned());
821 if (err != Error::NONE) {
822 mWriter.setError(getCommandLoc(), err);
823 }
824
825 return true;
826}
827
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500828bool ComposerClient::CommandReader::parseSetLayerBuffer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800829{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500830 if (length != CommandWriterBase::kSetLayerBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800831 return false;
832 }
833
Chia-I Wue1768352016-12-19 12:56:54 +0800834 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800835 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800836 auto buffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800837 auto fence = readFence();
838
839 auto err = lookupBuffer(BufferCache::LAYER_BUFFERS,
Chia-I Wu41a1c152017-03-09 15:41:59 -0800840 slot, useCache, buffer, &buffer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800841 if (err == Error::NONE) {
842 err = mHal.setLayerBuffer(mDisplay, mLayer, buffer, fence);
Chia-I Wu41a1c152017-03-09 15:41:59 -0800843
844 updateBuffer(BufferCache::LAYER_BUFFERS,
845 slot, useCache, buffer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800846 }
847 if (err != Error::NONE) {
848 close(fence);
849 mWriter.setError(getCommandLoc(), err);
850 }
851
852 return true;
853}
854
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500855bool ComposerClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800856{
857 // N rectangles
858 if (length % 4 != 0) {
859 return false;
860 }
861
862 auto damage = readRegion(length / 4);
863 auto err = mHal.setLayerSurfaceDamage(mDisplay, mLayer, damage);
864 if (err != Error::NONE) {
865 mWriter.setError(getCommandLoc(), err);
866 }
867
868 return true;
869}
870
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500871bool ComposerClient::CommandReader::parseSetLayerBlendMode(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800872{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500873 if (length != CommandWriterBase::kSetLayerBlendModeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800874 return false;
875 }
876
877 auto err = mHal.setLayerBlendMode(mDisplay, mLayer, readSigned());
878 if (err != Error::NONE) {
879 mWriter.setError(getCommandLoc(), err);
880 }
881
882 return true;
883}
884
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500885bool ComposerClient::CommandReader::parseSetLayerColor(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800886{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500887 if (length != CommandWriterBase::kSetLayerColorLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800888 return false;
889 }
890
891 auto err = mHal.setLayerColor(mDisplay, mLayer, readColor());
892 if (err != Error::NONE) {
893 mWriter.setError(getCommandLoc(), err);
894 }
895
896 return true;
897}
898
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500899bool ComposerClient::CommandReader::parseSetLayerCompositionType(
900 uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800901{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500902 if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800903 return false;
904 }
905
906 auto err = mHal.setLayerCompositionType(mDisplay, mLayer, readSigned());
907 if (err != Error::NONE) {
908 mWriter.setError(getCommandLoc(), err);
909 }
910
911 return true;
912}
913
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500914bool ComposerClient::CommandReader::parseSetLayerDataspace(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800915{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500916 if (length != CommandWriterBase::kSetLayerDataspaceLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800917 return false;
918 }
919
920 auto err = mHal.setLayerDataspace(mDisplay, mLayer, readSigned());
921 if (err != Error::NONE) {
922 mWriter.setError(getCommandLoc(), err);
923 }
924
925 return true;
926}
927
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500928bool ComposerClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800929{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500930 if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800931 return false;
932 }
933
934 auto err = mHal.setLayerDisplayFrame(mDisplay, mLayer, readRect());
935 if (err != Error::NONE) {
936 mWriter.setError(getCommandLoc(), err);
937 }
938
939 return true;
940}
941
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500942bool ComposerClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800943{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500944 if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800945 return false;
946 }
947
Dan Stoza0df10c42016-12-19 15:22:47 -0800948 auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
Chia-I Wubb61a722016-10-24 15:40:20 +0800949 if (err != Error::NONE) {
950 mWriter.setError(getCommandLoc(), err);
951 }
952
953 return true;
954}
955
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500956bool ComposerClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800957{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500958 if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800959 return false;
960 }
961
962 auto stream = readHandle();
963
Chia-I Wu41a1c152017-03-09 15:41:59 -0800964 auto err = lookupLayerSidebandStream(stream, &stream);
Chia-I Wubb61a722016-10-24 15:40:20 +0800965 if (err == Error::NONE) {
966 err = mHal.setLayerSidebandStream(mDisplay, mLayer, stream);
Chia-I Wu41a1c152017-03-09 15:41:59 -0800967
968 updateLayerSidebandStream(stream);
Chia-I Wubb61a722016-10-24 15:40:20 +0800969 }
970 if (err != Error::NONE) {
971 mWriter.setError(getCommandLoc(), err);
972 }
973
974 return true;
975}
976
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500977bool ComposerClient::CommandReader::parseSetLayerSourceCrop(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800978{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500979 if (length != CommandWriterBase::kSetLayerSourceCropLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800980 return false;
981 }
982
983 auto err = mHal.setLayerSourceCrop(mDisplay, mLayer, readFRect());
984 if (err != Error::NONE) {
985 mWriter.setError(getCommandLoc(), err);
986 }
987
988 return true;
989}
990
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500991bool ComposerClient::CommandReader::parseSetLayerTransform(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800992{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500993 if (length != CommandWriterBase::kSetLayerTransformLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800994 return false;
995 }
996
997 auto err = mHal.setLayerTransform(mDisplay, mLayer, readSigned());
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::parseSetLayerVisibleRegion(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +08001006{
1007 // N rectangles
1008 if (length % 4 != 0) {
1009 return false;
1010 }
1011
1012 auto region = readRegion(length / 4);
1013 auto err = mHal.setLayerVisibleRegion(mDisplay, mLayer, region);
1014 if (err != Error::NONE) {
1015 mWriter.setError(getCommandLoc(), err);
1016 }
1017
1018 return true;
1019}
1020
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001021bool ComposerClient::CommandReader::parseSetLayerZOrder(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +08001022{
Daniel Nicoarabd82b812017-01-17 11:15:26 -05001023 if (length != CommandWriterBase::kSetLayerZOrderLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +08001024 return false;
1025 }
1026
1027 auto err = mHal.setLayerZOrder(mDisplay, mLayer, read());
1028 if (err != Error::NONE) {
1029 mWriter.setError(getCommandLoc(), err);
1030 }
1031
1032 return true;
1033}
1034
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001035hwc_rect_t ComposerClient::CommandReader::readRect()
Chia-I Wubb61a722016-10-24 15:40:20 +08001036{
1037 return hwc_rect_t{
1038 readSigned(),
1039 readSigned(),
1040 readSigned(),
1041 readSigned(),
1042 };
1043}
1044
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001045std::vector<hwc_rect_t> ComposerClient::CommandReader::readRegion(size_t count)
Chia-I Wubb61a722016-10-24 15:40:20 +08001046{
1047 std::vector<hwc_rect_t> region;
1048 region.reserve(count);
1049 while (count > 0) {
1050 region.emplace_back(readRect());
1051 count--;
1052 }
1053
1054 return region;
1055}
1056
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001057hwc_frect_t ComposerClient::CommandReader::readFRect()
Chia-I Wubb61a722016-10-24 15:40:20 +08001058{
1059 return hwc_frect_t{
1060 readFloat(),
1061 readFloat(),
1062 readFloat(),
1063 readFloat(),
1064 };
1065}
1066
Chia-I Wu41a1c152017-03-09 15:41:59 -08001067Error ComposerClient::CommandReader::lookupBufferCacheEntryLocked(
1068 BufferCache cache, uint32_t slot, BufferCacheEntry** outEntry)
Chia-I Wubb61a722016-10-24 15:40:20 +08001069{
Chia-I Wubb61a722016-10-24 15:40:20 +08001070 auto dpy = mClient.mDisplayData.find(mDisplay);
1071 if (dpy == mClient.mDisplayData.end()) {
1072 return Error::BAD_DISPLAY;
1073 }
1074
Chia-I Wu41a1c152017-03-09 15:41:59 -08001075 BufferCacheEntry* entry = nullptr;
Chia-I Wubb61a722016-10-24 15:40:20 +08001076 switch (cache) {
1077 case BufferCache::CLIENT_TARGETS:
1078 if (slot < dpy->second.ClientTargets.size()) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001079 entry = &dpy->second.ClientTargets[slot];
Chia-I Wubb61a722016-10-24 15:40:20 +08001080 }
1081 break;
1082 case BufferCache::OUTPUT_BUFFERS:
1083 if (slot < dpy->second.OutputBuffers.size()) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001084 entry = &dpy->second.OutputBuffers[slot];
Chia-I Wubb61a722016-10-24 15:40:20 +08001085 }
1086 break;
1087 case BufferCache::LAYER_BUFFERS:
1088 {
1089 auto ly = dpy->second.Layers.find(mLayer);
1090 if (ly == dpy->second.Layers.end()) {
1091 return Error::BAD_LAYER;
1092 }
1093 if (slot < ly->second.Buffers.size()) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001094 entry = &ly->second.Buffers[slot];
Chia-I Wubb61a722016-10-24 15:40:20 +08001095 }
1096 }
1097 break;
1098 case BufferCache::LAYER_SIDEBAND_STREAMS:
1099 {
1100 auto ly = dpy->second.Layers.find(mLayer);
1101 if (ly == dpy->second.Layers.end()) {
1102 return Error::BAD_LAYER;
1103 }
1104 if (slot == 0) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001105 entry = &ly->second.SidebandStream;
Chia-I Wubb61a722016-10-24 15:40:20 +08001106 }
1107 }
1108 break;
1109 default:
1110 break;
1111 }
1112
Chia-I Wu41a1c152017-03-09 15:41:59 -08001113 if (!entry) {
1114 ALOGW("invalid buffer slot %" PRIu32, slot);
Chia-I Wubb61a722016-10-24 15:40:20 +08001115 return Error::BAD_PARAMETER;
1116 }
1117
Chia-I Wu41a1c152017-03-09 15:41:59 -08001118 *outEntry = entry;
1119
1120 return Error::NONE;
1121}
1122
1123Error ComposerClient::CommandReader::lookupBuffer(BufferCache cache,
1124 uint32_t slot, bool useCache, buffer_handle_t handle,
1125 buffer_handle_t* outHandle)
1126{
Chia-I Wubb61a722016-10-24 15:40:20 +08001127 if (useCache) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001128 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1129
1130 BufferCacheEntry* entry;
1131 Error error = lookupBufferCacheEntryLocked(cache, slot, &entry);
1132 if (error != Error::NONE) {
1133 return error;
1134 }
1135
1136 // input handle is ignored
1137 *outHandle = entry->getHandle();
Chia-I Wubb61a722016-10-24 15:40:20 +08001138 } else {
1139 if (!sHandleImporter.importBuffer(handle)) {
1140 return Error::NO_RESOURCES;
1141 }
1142
Chia-I Wu41a1c152017-03-09 15:41:59 -08001143 *outHandle = handle;
Chia-I Wubb61a722016-10-24 15:40:20 +08001144 }
1145
1146 return Error::NONE;
1147}
1148
Chia-I Wu41a1c152017-03-09 15:41:59 -08001149void ComposerClient::CommandReader::updateBuffer(BufferCache cache,
1150 uint32_t slot, bool useCache, buffer_handle_t handle)
1151{
1152 // handle was looked up from cache
1153 if (useCache) {
1154 return;
1155 }
1156
1157 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1158
1159 BufferCacheEntry* entry = nullptr;
1160 lookupBufferCacheEntryLocked(cache, slot, &entry);
1161 LOG_FATAL_IF(!entry, "failed to find the cache entry to update");
1162
1163 *entry = handle;
1164}
1165
Chia-I Wubb61a722016-10-24 15:40:20 +08001166} // namespace implementation
1167} // namespace V2_1
1168} // namespace composer
1169} // namespace graphics
1170} // namespace hardware
1171} // namespace android