blob: 72ba8f8bfb794d91593fa6b1017fa60dd31b3acd [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 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,
709 slot, useCache, clientTarget);
710 if (err == Error::NONE) {
711 err = mHal.setClientTarget(mDisplay, clientTarget, fence,
712 dataspace, damage);
713 }
714 if (err != Error::NONE) {
715 close(fence);
716 mWriter.setError(getCommandLoc(), err);
717 }
718
719 return true;
720}
721
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500722bool ComposerClient::CommandReader::parseSetOutputBuffer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800723{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500724 if (length != CommandWriterBase::kSetOutputBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800725 return false;
726 }
727
Chia-I Wue1768352016-12-19 12:56:54 +0800728 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800729 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800730 auto outputBuffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800731 auto fence = readFence();
732
733 auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS,
734 slot, useCache, outputBuffer);
735 if (err == Error::NONE) {
736 err = mHal.setOutputBuffer(mDisplay, outputBuffer, fence);
737 }
738 if (err != Error::NONE) {
739 close(fence);
740 mWriter.setError(getCommandLoc(), err);
741 }
742
743 return true;
744}
745
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500746bool ComposerClient::CommandReader::parseValidateDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800747{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500748 if (length != CommandWriterBase::kValidateDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800749 return false;
750 }
751
752 std::vector<Layer> changedLayers;
753 std::vector<IComposerClient::Composition> compositionTypes;
Chia-I Wue1768352016-12-19 12:56:54 +0800754 uint32_t displayRequestMask = 0x0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800755 std::vector<Layer> requestedLayers;
756 std::vector<uint32_t> requestMasks;
757
Chia-I Wue1768352016-12-19 12:56:54 +0800758 auto err = mHal.validateDisplay(mDisplay, &changedLayers,
759 &compositionTypes, &displayRequestMask,
760 &requestedLayers, &requestMasks);
Chia-I Wubb61a722016-10-24 15:40:20 +0800761 if (err == Error::NONE) {
762 mWriter.setChangedCompositionTypes(changedLayers,
763 compositionTypes);
764 mWriter.setDisplayRequests(displayRequestMask,
765 requestedLayers, requestMasks);
766 } else {
767 mWriter.setError(getCommandLoc(), err);
768 }
769
770 return true;
771}
772
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500773bool ComposerClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800774{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500775 if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800776 return false;
777 }
778
779 auto err = mHal.acceptDisplayChanges(mDisplay);
780 if (err != Error::NONE) {
781 mWriter.setError(getCommandLoc(), err);
782 }
783
784 return true;
785}
786
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500787bool ComposerClient::CommandReader::parsePresentDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800788{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500789 if (length != CommandWriterBase::kPresentDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800790 return false;
791 }
792
Chia-I Wue1768352016-12-19 12:56:54 +0800793 int presentFence = -1;
Chia-I Wubb61a722016-10-24 15:40:20 +0800794 std::vector<Layer> layers;
795 std::vector<int> fences;
Chia-I Wue1768352016-12-19 12:56:54 +0800796 auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
Chia-I Wubb61a722016-10-24 15:40:20 +0800797 if (err == Error::NONE) {
798 mWriter.setPresentFence(presentFence);
799 mWriter.setReleaseFences(layers, fences);
800 } else {
801 mWriter.setError(getCommandLoc(), err);
802 }
803
804 return true;
805}
806
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500807bool ComposerClient::CommandReader::parseSetLayerCursorPosition(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800808{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500809 if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800810 return false;
811 }
812
813 auto err = mHal.setLayerCursorPosition(mDisplay, mLayer,
814 readSigned(), readSigned());
815 if (err != Error::NONE) {
816 mWriter.setError(getCommandLoc(), err);
817 }
818
819 return true;
820}
821
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500822bool ComposerClient::CommandReader::parseSetLayerBuffer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800823{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500824 if (length != CommandWriterBase::kSetLayerBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800825 return false;
826 }
827
Chia-I Wue1768352016-12-19 12:56:54 +0800828 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800829 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800830 auto buffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800831 auto fence = readFence();
832
833 auto err = lookupBuffer(BufferCache::LAYER_BUFFERS,
834 slot, useCache, buffer);
835 if (err == Error::NONE) {
836 err = mHal.setLayerBuffer(mDisplay, mLayer, buffer, fence);
837 }
838 if (err != Error::NONE) {
839 close(fence);
840 mWriter.setError(getCommandLoc(), err);
841 }
842
843 return true;
844}
845
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500846bool ComposerClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800847{
848 // N rectangles
849 if (length % 4 != 0) {
850 return false;
851 }
852
853 auto damage = readRegion(length / 4);
854 auto err = mHal.setLayerSurfaceDamage(mDisplay, mLayer, damage);
855 if (err != Error::NONE) {
856 mWriter.setError(getCommandLoc(), err);
857 }
858
859 return true;
860}
861
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500862bool ComposerClient::CommandReader::parseSetLayerBlendMode(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800863{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500864 if (length != CommandWriterBase::kSetLayerBlendModeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800865 return false;
866 }
867
868 auto err = mHal.setLayerBlendMode(mDisplay, mLayer, readSigned());
869 if (err != Error::NONE) {
870 mWriter.setError(getCommandLoc(), err);
871 }
872
873 return true;
874}
875
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500876bool ComposerClient::CommandReader::parseSetLayerColor(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800877{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500878 if (length != CommandWriterBase::kSetLayerColorLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800879 return false;
880 }
881
882 auto err = mHal.setLayerColor(mDisplay, mLayer, readColor());
883 if (err != Error::NONE) {
884 mWriter.setError(getCommandLoc(), err);
885 }
886
887 return true;
888}
889
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500890bool ComposerClient::CommandReader::parseSetLayerCompositionType(
891 uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800892{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500893 if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800894 return false;
895 }
896
897 auto err = mHal.setLayerCompositionType(mDisplay, mLayer, readSigned());
898 if (err != Error::NONE) {
899 mWriter.setError(getCommandLoc(), err);
900 }
901
902 return true;
903}
904
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500905bool ComposerClient::CommandReader::parseSetLayerDataspace(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800906{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500907 if (length != CommandWriterBase::kSetLayerDataspaceLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800908 return false;
909 }
910
911 auto err = mHal.setLayerDataspace(mDisplay, mLayer, readSigned());
912 if (err != Error::NONE) {
913 mWriter.setError(getCommandLoc(), err);
914 }
915
916 return true;
917}
918
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500919bool ComposerClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800920{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500921 if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800922 return false;
923 }
924
925 auto err = mHal.setLayerDisplayFrame(mDisplay, mLayer, readRect());
926 if (err != Error::NONE) {
927 mWriter.setError(getCommandLoc(), err);
928 }
929
930 return true;
931}
932
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500933bool ComposerClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800934{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500935 if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800936 return false;
937 }
938
Dan Stoza0df10c42016-12-19 15:22:47 -0800939 auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
Chia-I Wubb61a722016-10-24 15:40:20 +0800940 if (err != Error::NONE) {
941 mWriter.setError(getCommandLoc(), err);
942 }
943
944 return true;
945}
946
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500947bool ComposerClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800948{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500949 if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800950 return false;
951 }
952
953 auto stream = readHandle();
954
955 auto err = lookupLayerSidebandStream(stream);
956 if (err == Error::NONE) {
957 err = mHal.setLayerSidebandStream(mDisplay, mLayer, stream);
958 }
959 if (err != Error::NONE) {
960 mWriter.setError(getCommandLoc(), err);
961 }
962
963 return true;
964}
965
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500966bool ComposerClient::CommandReader::parseSetLayerSourceCrop(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800967{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500968 if (length != CommandWriterBase::kSetLayerSourceCropLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800969 return false;
970 }
971
972 auto err = mHal.setLayerSourceCrop(mDisplay, mLayer, readFRect());
973 if (err != Error::NONE) {
974 mWriter.setError(getCommandLoc(), err);
975 }
976
977 return true;
978}
979
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500980bool ComposerClient::CommandReader::parseSetLayerTransform(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800981{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500982 if (length != CommandWriterBase::kSetLayerTransformLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800983 return false;
984 }
985
986 auto err = mHal.setLayerTransform(mDisplay, mLayer, readSigned());
987 if (err != Error::NONE) {
988 mWriter.setError(getCommandLoc(), err);
989 }
990
991 return true;
992}
993
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500994bool ComposerClient::CommandReader::parseSetLayerVisibleRegion(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800995{
996 // N rectangles
997 if (length % 4 != 0) {
998 return false;
999 }
1000
1001 auto region = readRegion(length / 4);
1002 auto err = mHal.setLayerVisibleRegion(mDisplay, mLayer, region);
1003 if (err != Error::NONE) {
1004 mWriter.setError(getCommandLoc(), err);
1005 }
1006
1007 return true;
1008}
1009
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001010bool ComposerClient::CommandReader::parseSetLayerZOrder(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +08001011{
Daniel Nicoarabd82b812017-01-17 11:15:26 -05001012 if (length != CommandWriterBase::kSetLayerZOrderLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +08001013 return false;
1014 }
1015
1016 auto err = mHal.setLayerZOrder(mDisplay, mLayer, read());
1017 if (err != Error::NONE) {
1018 mWriter.setError(getCommandLoc(), err);
1019 }
1020
1021 return true;
1022}
1023
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001024hwc_rect_t ComposerClient::CommandReader::readRect()
Chia-I Wubb61a722016-10-24 15:40:20 +08001025{
1026 return hwc_rect_t{
1027 readSigned(),
1028 readSigned(),
1029 readSigned(),
1030 readSigned(),
1031 };
1032}
1033
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001034std::vector<hwc_rect_t> ComposerClient::CommandReader::readRegion(size_t count)
Chia-I Wubb61a722016-10-24 15:40:20 +08001035{
1036 std::vector<hwc_rect_t> region;
1037 region.reserve(count);
1038 while (count > 0) {
1039 region.emplace_back(readRect());
1040 count--;
1041 }
1042
1043 return region;
1044}
1045
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001046hwc_frect_t ComposerClient::CommandReader::readFRect()
Chia-I Wubb61a722016-10-24 15:40:20 +08001047{
1048 return hwc_frect_t{
1049 readFloat(),
1050 readFloat(),
1051 readFloat(),
1052 readFloat(),
1053 };
1054}
1055
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001056Error ComposerClient::CommandReader::lookupBuffer(BufferCache cache,
1057 uint32_t slot, bool useCache, buffer_handle_t& handle)
Chia-I Wubb61a722016-10-24 15:40:20 +08001058{
1059 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1060
1061 auto dpy = mClient.mDisplayData.find(mDisplay);
1062 if (dpy == mClient.mDisplayData.end()) {
1063 return Error::BAD_DISPLAY;
1064 }
1065
1066 BufferClone* clone = nullptr;
1067 switch (cache) {
1068 case BufferCache::CLIENT_TARGETS:
1069 if (slot < dpy->second.ClientTargets.size()) {
1070 clone = &dpy->second.ClientTargets[slot];
1071 }
1072 break;
1073 case BufferCache::OUTPUT_BUFFERS:
1074 if (slot < dpy->second.OutputBuffers.size()) {
1075 clone = &dpy->second.OutputBuffers[slot];
1076 }
1077 break;
1078 case BufferCache::LAYER_BUFFERS:
1079 {
1080 auto ly = dpy->second.Layers.find(mLayer);
1081 if (ly == dpy->second.Layers.end()) {
1082 return Error::BAD_LAYER;
1083 }
1084 if (slot < ly->second.Buffers.size()) {
1085 clone = &ly->second.Buffers[slot];
1086 }
1087 }
1088 break;
1089 case BufferCache::LAYER_SIDEBAND_STREAMS:
1090 {
1091 auto ly = dpy->second.Layers.find(mLayer);
1092 if (ly == dpy->second.Layers.end()) {
1093 return Error::BAD_LAYER;
1094 }
1095 if (slot == 0) {
1096 clone = &ly->second.SidebandStream;
1097 }
1098 }
1099 break;
1100 default:
1101 break;
1102 }
1103
1104 if (!clone) {
1105 ALOGW("invalid buffer slot");
1106 return Error::BAD_PARAMETER;
1107 }
1108
1109 // use or update cache
1110 if (useCache) {
1111 handle = *clone;
1112 } else {
1113 if (!sHandleImporter.importBuffer(handle)) {
1114 return Error::NO_RESOURCES;
1115 }
1116
1117 *clone = handle;
1118 }
1119
1120 return Error::NONE;
1121}
1122
1123} // namespace implementation
1124} // namespace V2_1
1125} // namespace composer
1126} // namespace graphics
1127} // namespace hardware
1128} // namespace android