blob: 5a96e298fcbb8213ec0350f1631b8ec07cf05eb9 [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
Chia-I Wu2ae85702017-04-20 11:01:18 -070019#include <android/hardware/graphics/mapper/2.0/IMapper.h>
Chia-I Wubb61a722016-10-24 15:40:20 +080020#include <log/log.h>
21
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -050022#include "ComposerClient.h"
Fabien Sanglard9b117a42017-03-21 09:39:35 -070023#include "ComposerBase.h"
Chia-I Wubb61a722016-10-24 15:40:20 +080024#include "IComposerCommandBuffer.h"
25
26namespace android {
27namespace hardware {
28namespace graphics {
29namespace composer {
30namespace V2_1 {
31namespace implementation {
32
33namespace {
34
Chia-I Wu2ae85702017-04-20 11:01:18 -070035using MapperError = android::hardware::graphics::mapper::V2_0::Error;
36using android::hardware::graphics::mapper::V2_0::IMapper;
37
Chia-I Wubb61a722016-10-24 15:40:20 +080038class HandleImporter {
39public:
Chia-I Wubb61a722016-10-24 15:40:20 +080040 bool initialize()
41 {
42 // allow only one client
43 if (mInitialized) {
44 return false;
45 }
46
Chia-I Wu2ae85702017-04-20 11:01:18 -070047 mMapper = IMapper::getService();
Chia-I Wubb61a722016-10-24 15:40:20 +080048
49 mInitialized = true;
50 return true;
51 }
52
53 void cleanup()
54 {
Chia-I Wu2ae85702017-04-20 11:01:18 -070055 mMapper.clear();
Chia-I Wubb61a722016-10-24 15:40:20 +080056 mInitialized = false;
57 }
58
59 // In IComposer, any buffer_handle_t is owned by the caller and we need to
60 // make a clone for hwcomposer2. We also need to translate empty handle
61 // to nullptr. This function does that, in-place.
62 bool importBuffer(buffer_handle_t& handle)
63 {
64 if (!handle) {
65 return true;
66 }
67
68 if (!handle->numFds && !handle->numInts) {
69 handle = nullptr;
70 return true;
71 }
72
Chia-I Wu2ae85702017-04-20 11:01:18 -070073 MapperError error;
74 buffer_handle_t importedHandle;
75 mMapper->importBuffer(
76 hidl_handle(handle),
77 [&](const auto& tmpError, const auto& tmpBufferHandle) {
78 error = tmpError;
79 importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle);
80 });
81 if (error != MapperError::NONE) {
Chia-I Wubb61a722016-10-24 15:40:20 +080082 return false;
83 }
84
Chia-I Wu2ae85702017-04-20 11:01:18 -070085 handle = importedHandle;
86
Chia-I Wubb61a722016-10-24 15:40:20 +080087 return true;
88 }
89
90 void freeBuffer(buffer_handle_t handle)
91 {
92 if (!handle) {
93 return;
94 }
95
Chia-I Wu2ae85702017-04-20 11:01:18 -070096 mMapper->freeBuffer(const_cast<native_handle_t*>(handle));
Chia-I Wubb61a722016-10-24 15:40:20 +080097 }
98
99private:
Chia-I Wu2ae85702017-04-20 11:01:18 -0700100 bool mInitialized = false;
101 sp<IMapper> mMapper;
Chia-I Wubb61a722016-10-24 15:40:20 +0800102};
103
104HandleImporter sHandleImporter;
105
106} // anonymous namespace
107
Chia-I Wu41a1c152017-03-09 15:41:59 -0800108BufferCacheEntry::BufferCacheEntry()
Chia-I Wubb61a722016-10-24 15:40:20 +0800109 : mHandle(nullptr)
110{
111}
112
Chia-I Wu41a1c152017-03-09 15:41:59 -0800113BufferCacheEntry::BufferCacheEntry(BufferCacheEntry&& other)
Chia-I Wubb61a722016-10-24 15:40:20 +0800114{
115 mHandle = other.mHandle;
116 other.mHandle = nullptr;
117}
118
Chia-I Wu41a1c152017-03-09 15:41:59 -0800119BufferCacheEntry& BufferCacheEntry::operator=(buffer_handle_t handle)
Chia-I Wubb61a722016-10-24 15:40:20 +0800120{
121 clear();
122 mHandle = handle;
123 return *this;
124}
125
Chia-I Wu41a1c152017-03-09 15:41:59 -0800126BufferCacheEntry::~BufferCacheEntry()
Chia-I Wubb61a722016-10-24 15:40:20 +0800127{
128 clear();
129}
130
Chia-I Wu41a1c152017-03-09 15:41:59 -0800131void BufferCacheEntry::clear()
Chia-I Wubb61a722016-10-24 15:40:20 +0800132{
133 if (mHandle) {
134 sHandleImporter.freeBuffer(mHandle);
135 }
136}
137
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500138ComposerClient::ComposerClient(ComposerBase& hal)
139 : mHal(hal), mWriter(kWriterInitialSize)
Chia-I Wubb61a722016-10-24 15:40:20 +0800140{
Chia-I Wubb61a722016-10-24 15:40:20 +0800141}
142
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500143ComposerClient::~ComposerClient()
Chia-I Wubb61a722016-10-24 15:40:20 +0800144{
Chia-I Wu6c84f7e2017-03-08 15:30:35 -0800145 // We want to call hwc2_close here (and move hwc2_open to the
146 // constructor), with the assumption that hwc2_close would
147 //
148 // - clean up all resources owned by the client
149 // - make sure all displays are blank (since there is no layer)
150 //
151 // But since SF used to crash at this point, different hwcomposer2
152 // implementations behave differently on hwc2_close. Our only portable
153 // choice really is to abort(). But that is not an option anymore
154 // because we might also have VTS or VR as clients that can come and go.
155 //
156 // Below we manually clean all resources (layers and virtual
157 // displays), and perform a presentDisplay afterwards.
158 ALOGW("destroying composer client");
Chia-I Wu43398712017-02-17 12:38:50 -0800159
Chia-I Wubb61a722016-10-24 15:40:20 +0800160 mHal.enableCallback(false);
Chia-I Wubb61a722016-10-24 15:40:20 +0800161
Chia-I Wu6c84f7e2017-03-08 15:30:35 -0800162 // no need to grab the mutex as any in-flight hwbinder call would have
163 // kept the client alive
Chia-I Wubb61a722016-10-24 15:40:20 +0800164 for (const auto& dpy : mDisplayData) {
Chia-I Wu6c84f7e2017-03-08 15:30:35 -0800165 ALOGW("destroying client resources for display %" PRIu64, dpy.first);
166
Chia-I Wubb61a722016-10-24 15:40:20 +0800167 for (const auto& ly : dpy.second.Layers) {
168 mHal.destroyLayer(dpy.first, ly.first);
169 }
170
171 if (dpy.second.IsVirtual) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800172 mHal.destroyVirtualDisplay(dpy.first);
Chia-I Wu6c84f7e2017-03-08 15:30:35 -0800173 } else {
174 ALOGW("performing a final presentDisplay");
175
176 std::vector<Layer> changedLayers;
177 std::vector<IComposerClient::Composition> compositionTypes;
178 uint32_t displayRequestMask = 0;
179 std::vector<Layer> requestedLayers;
180 std::vector<uint32_t> requestMasks;
181 mHal.validateDisplay(dpy.first, &changedLayers, &compositionTypes,
182 &displayRequestMask, &requestedLayers, &requestMasks);
183
184 mHal.acceptDisplayChanges(dpy.first);
185
186 int32_t presentFence = -1;
187 std::vector<Layer> releasedLayers;
188 std::vector<int32_t> releaseFences;
189 mHal.presentDisplay(dpy.first, &presentFence, &releasedLayers, &releaseFences);
190 if (presentFence >= 0) {
191 close(presentFence);
192 }
193 for (auto fence : releaseFences) {
194 if (fence >= 0) {
195 close(fence);
196 }
197 }
Chia-I Wubb61a722016-10-24 15:40:20 +0800198 }
199 }
200
201 mDisplayData.clear();
202
203 sHandleImporter.cleanup();
Chia-I Wu6c84f7e2017-03-08 15:30:35 -0800204
205 mHal.removeClient();
206
207 ALOGW("removed composer client");
Chia-I Wubb61a722016-10-24 15:40:20 +0800208}
209
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500210void ComposerClient::initialize()
211{
212 mReader = createCommandReader();
213 if (!sHandleImporter.initialize()) {
214 LOG_ALWAYS_FATAL("failed to initialize handle importer");
215 }
216}
217
218void ComposerClient::onHotplug(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800219 IComposerCallback::Connection connected)
220{
221 {
222 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
223
224 if (connected == IComposerCallback::Connection::CONNECTED) {
225 mDisplayData.emplace(display, DisplayData(false));
226 } else if (connected == IComposerCallback::Connection::DISCONNECTED) {
227 mDisplayData.erase(display);
228 }
229 }
230
Chia-I Wu43398712017-02-17 12:38:50 -0800231 auto ret = mCallback->onHotplug(display, connected);
232 ALOGE_IF(!ret.isOk(), "failed to send onHotplug: %s",
233 ret.description().c_str());
Chia-I Wubb61a722016-10-24 15:40:20 +0800234}
235
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500236void ComposerClient::onRefresh(Display display)
Chia-I Wubb61a722016-10-24 15:40:20 +0800237{
Chia-I Wu43398712017-02-17 12:38:50 -0800238 auto ret = mCallback->onRefresh(display);
239 ALOGE_IF(!ret.isOk(), "failed to send onRefresh: %s",
240 ret.description().c_str());
Chia-I Wubb61a722016-10-24 15:40:20 +0800241}
242
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500243void ComposerClient::onVsync(Display display, int64_t timestamp)
Chia-I Wubb61a722016-10-24 15:40:20 +0800244{
Chia-I Wu43398712017-02-17 12:38:50 -0800245 auto ret = mCallback->onVsync(display, timestamp);
246 ALOGE_IF(!ret.isOk(), "failed to send onVsync: %s",
247 ret.description().c_str());
Chia-I Wubb61a722016-10-24 15:40:20 +0800248}
249
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500250Return<void> ComposerClient::registerCallback(
251 const sp<IComposerCallback>& callback)
Chia-I Wubb61a722016-10-24 15:40:20 +0800252{
253 // no locking as we require this function to be called only once
254 mCallback = callback;
255 mHal.enableCallback(callback != nullptr);
256
257 return Void();
258}
259
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500260Return<uint32_t> ComposerClient::getMaxVirtualDisplayCount()
Chia-I Wubb61a722016-10-24 15:40:20 +0800261{
262 return mHal.getMaxVirtualDisplayCount();
263}
264
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500265Return<void> ComposerClient::createVirtualDisplay(uint32_t width,
266 uint32_t height, PixelFormat formatHint, uint32_t outputBufferSlotCount,
Chia-I Wubb61a722016-10-24 15:40:20 +0800267 createVirtualDisplay_cb hidl_cb)
268{
Chia-I Wue1768352016-12-19 12:56:54 +0800269 Display display = 0;
270 Error err = mHal.createVirtualDisplay(width, height,
271 &formatHint, &display);
Chia-I Wubb61a722016-10-24 15:40:20 +0800272 if (err == Error::NONE) {
273 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
274
275 auto dpy = mDisplayData.emplace(display, DisplayData(true)).first;
276 dpy->second.OutputBuffers.resize(outputBufferSlotCount);
277 }
278
279 hidl_cb(err, display, formatHint);
280 return Void();
281}
282
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500283Return<Error> ComposerClient::destroyVirtualDisplay(Display display)
Chia-I Wubb61a722016-10-24 15:40:20 +0800284{
285 Error err = mHal.destroyVirtualDisplay(display);
286 if (err == Error::NONE) {
287 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
288
289 mDisplayData.erase(display);
290 }
291
292 return err;
293}
294
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500295Return<void> ComposerClient::createLayer(Display display,
296 uint32_t bufferSlotCount, createLayer_cb hidl_cb)
Chia-I Wubb61a722016-10-24 15:40:20 +0800297{
Chia-I Wue1768352016-12-19 12:56:54 +0800298 Layer layer = 0;
299 Error err = mHal.createLayer(display, &layer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800300 if (err == Error::NONE) {
301 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
302
303 auto dpy = mDisplayData.find(display);
304 auto ly = dpy->second.Layers.emplace(layer, LayerBuffers()).first;
305 ly->second.Buffers.resize(bufferSlotCount);
306 }
307
308 hidl_cb(err, layer);
309 return Void();
310}
311
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500312Return<Error> ComposerClient::destroyLayer(Display display, Layer layer)
Chia-I Wubb61a722016-10-24 15:40:20 +0800313{
314 Error err = mHal.destroyLayer(display, layer);
315 if (err == Error::NONE) {
316 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
317
318 auto dpy = mDisplayData.find(display);
319 dpy->second.Layers.erase(layer);
320 }
321
322 return err;
323}
324
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500325Return<void> ComposerClient::getActiveConfig(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800326 getActiveConfig_cb hidl_cb)
327{
Chia-I Wue1768352016-12-19 12:56:54 +0800328 Config config = 0;
329 Error err = mHal.getActiveConfig(display, &config);
Chia-I Wubb61a722016-10-24 15:40:20 +0800330
331 hidl_cb(err, config);
332 return Void();
333}
334
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500335Return<Error> ComposerClient::getClientTargetSupport(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800336 uint32_t width, uint32_t height,
337 PixelFormat format, Dataspace dataspace)
338{
339 Error err = mHal.getClientTargetSupport(display,
340 width, height, format, dataspace);
341 return err;
342}
343
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500344Return<void> ComposerClient::getColorModes(Display display,
345 getColorModes_cb hidl_cb)
Chia-I Wubb61a722016-10-24 15:40:20 +0800346{
347 hidl_vec<ColorMode> modes;
Chia-I Wue1768352016-12-19 12:56:54 +0800348 Error err = mHal.getColorModes(display, &modes);
Chia-I Wubb61a722016-10-24 15:40:20 +0800349
350 hidl_cb(err, modes);
351 return Void();
352}
353
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500354Return<void> ComposerClient::getDisplayAttribute(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800355 Config config, Attribute attribute,
356 getDisplayAttribute_cb hidl_cb)
357{
Chia-I Wue1768352016-12-19 12:56:54 +0800358 int32_t value = 0;
359 Error err = mHal.getDisplayAttribute(display, config, attribute, &value);
Chia-I Wubb61a722016-10-24 15:40:20 +0800360
361 hidl_cb(err, value);
362 return Void();
363}
364
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500365Return<void> ComposerClient::getDisplayConfigs(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800366 getDisplayConfigs_cb hidl_cb)
367{
368 hidl_vec<Config> configs;
Chia-I Wue1768352016-12-19 12:56:54 +0800369 Error err = mHal.getDisplayConfigs(display, &configs);
Chia-I Wubb61a722016-10-24 15:40:20 +0800370
371 hidl_cb(err, configs);
372 return Void();
373}
374
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500375Return<void> ComposerClient::getDisplayName(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800376 getDisplayName_cb hidl_cb)
377{
378 hidl_string name;
Chia-I Wue1768352016-12-19 12:56:54 +0800379 Error err = mHal.getDisplayName(display, &name);
Chia-I Wubb61a722016-10-24 15:40:20 +0800380
381 hidl_cb(err, name);
382 return Void();
383}
384
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500385Return<void> ComposerClient::getDisplayType(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800386 getDisplayType_cb hidl_cb)
387{
Chia-I Wue1768352016-12-19 12:56:54 +0800388 DisplayType type = DisplayType::INVALID;
389 Error err = mHal.getDisplayType(display, &type);
Chia-I Wubb61a722016-10-24 15:40:20 +0800390
391 hidl_cb(err, type);
392 return Void();
393}
394
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500395Return<void> ComposerClient::getDozeSupport(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800396 getDozeSupport_cb hidl_cb)
397{
Chia-I Wue1768352016-12-19 12:56:54 +0800398 bool support = false;
399 Error err = mHal.getDozeSupport(display, &support);
Chia-I Wubb61a722016-10-24 15:40:20 +0800400
401 hidl_cb(err, support);
402 return Void();
403}
404
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500405Return<void> ComposerClient::getHdrCapabilities(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800406 getHdrCapabilities_cb hidl_cb)
407{
408 hidl_vec<Hdr> types;
409 float max_lumi = 0.0f;
410 float max_avg_lumi = 0.0f;
411 float min_lumi = 0.0f;
Chia-I Wue1768352016-12-19 12:56:54 +0800412 Error err = mHal.getHdrCapabilities(display, &types,
413 &max_lumi, &max_avg_lumi, &min_lumi);
Chia-I Wubb61a722016-10-24 15:40:20 +0800414
415 hidl_cb(err, types, max_lumi, max_avg_lumi, min_lumi);
416 return Void();
417}
418
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500419Return<Error> ComposerClient::setClientTargetSlotCount(Display display,
Chia-I Wubb61a722016-10-24 15:40:20 +0800420 uint32_t clientTargetSlotCount)
421{
422 std::lock_guard<std::mutex> lock(mDisplayDataMutex);
423
424 auto dpy = mDisplayData.find(display);
425 if (dpy == mDisplayData.end()) {
426 return Error::BAD_DISPLAY;
427 }
428
429 dpy->second.ClientTargets.resize(clientTargetSlotCount);
430
431 return Error::NONE;
432}
433
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500434Return<Error> ComposerClient::setActiveConfig(Display display, Config config)
Chia-I Wubb61a722016-10-24 15:40:20 +0800435{
436 Error err = mHal.setActiveConfig(display, config);
437 return err;
438}
439
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500440Return<Error> ComposerClient::setColorMode(Display display, ColorMode mode)
Chia-I Wubb61a722016-10-24 15:40:20 +0800441{
442 Error err = mHal.setColorMode(display, mode);
443 return err;
444}
445
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500446Return<Error> ComposerClient::setPowerMode(Display display, PowerMode mode)
Chia-I Wubb61a722016-10-24 15:40:20 +0800447{
448 Error err = mHal.setPowerMode(display, mode);
449 return err;
450}
451
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500452Return<Error> ComposerClient::setVsyncEnabled(Display display, Vsync enabled)
Chia-I Wubb61a722016-10-24 15:40:20 +0800453{
454 Error err = mHal.setVsyncEnabled(display, enabled);
455 return err;
456}
457
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500458Return<Error> ComposerClient::setInputCommandQueue(
Hridya Valsaraju33351da2016-12-27 12:40:01 -0800459 const MQDescriptorSync<uint32_t>& descriptor)
Chia-I Wubb61a722016-10-24 15:40:20 +0800460{
461 std::lock_guard<std::mutex> lock(mCommandMutex);
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500462 return mReader->setMQDescriptor(descriptor) ?
Chia-I Wubb61a722016-10-24 15:40:20 +0800463 Error::NONE : Error::NO_RESOURCES;
464}
465
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500466Return<void> ComposerClient::getOutputCommandQueue(
Chia-I Wubb61a722016-10-24 15:40:20 +0800467 getOutputCommandQueue_cb hidl_cb)
468{
469 // no locking as we require this function to be called inside
470 // executeCommands_cb
471
472 auto outDescriptor = mWriter.getMQDescriptor();
473 if (outDescriptor) {
474 hidl_cb(Error::NONE, *outDescriptor);
475 } else {
Hridya Valsaraju790db102017-01-10 08:58:23 -0800476 hidl_cb(Error::NO_RESOURCES, CommandQueueType::Descriptor());
Chia-I Wubb61a722016-10-24 15:40:20 +0800477 }
478
479 return Void();
480}
481
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500482Return<void> ComposerClient::executeCommands(uint32_t inLength,
Chia-I Wubb61a722016-10-24 15:40:20 +0800483 const hidl_vec<hidl_handle>& inHandles,
484 executeCommands_cb hidl_cb)
485{
486 std::lock_guard<std::mutex> lock(mCommandMutex);
487
488 bool outChanged = false;
489 uint32_t outLength = 0;
490 hidl_vec<hidl_handle> outHandles;
491
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500492 if (!mReader->readQueue(inLength, inHandles)) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800493 hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
494 return Void();
495 }
496
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500497 Error err = mReader->parse();
Chia-I Wubb61a722016-10-24 15:40:20 +0800498 if (err == Error::NONE &&
Chia-I Wue1768352016-12-19 12:56:54 +0800499 !mWriter.writeQueue(&outChanged, &outLength, &outHandles)) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800500 err = Error::NO_RESOURCES;
501 }
502
503 hidl_cb(err, outChanged, outLength, outHandles);
504
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500505 mReader->reset();
Chia-I Wubb61a722016-10-24 15:40:20 +0800506 mWriter.reset();
507
508 return Void();
509}
510
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500511std::unique_ptr<ComposerClient::CommandReader>
512ComposerClient::createCommandReader()
513{
514 return std::unique_ptr<ComposerClient::CommandReader>(
515 new CommandReader(*this));
516}
517
518ComposerClient::CommandReader::CommandReader(ComposerClient& client)
Chia-I Wubb61a722016-10-24 15:40:20 +0800519 : mClient(client), mHal(client.mHal), mWriter(client.mWriter)
520{
521}
522
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500523ComposerClient::CommandReader::~CommandReader()
524{
525}
526
527Error ComposerClient::CommandReader::parse()
Chia-I Wubb61a722016-10-24 15:40:20 +0800528{
529 IComposerClient::Command command;
Chia-I Wue1768352016-12-19 12:56:54 +0800530 uint16_t length = 0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800531
532 while (!isEmpty()) {
Chia-I Wue1768352016-12-19 12:56:54 +0800533 if (!beginCommand(&command, &length)) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800534 break;
535 }
536
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500537 bool parsed = parseCommand(command, length);
Chia-I Wubb61a722016-10-24 15:40:20 +0800538 endCommand();
539
540 if (!parsed) {
541 ALOGE("failed to parse command 0x%x, length %" PRIu16,
542 command, length);
543 break;
544 }
545 }
546
547 return (isEmpty()) ? Error::NONE : Error::BAD_PARAMETER;
548}
549
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500550bool ComposerClient::CommandReader::parseCommand(
551 IComposerClient::Command command, uint16_t length) {
552 switch (command) {
553 case IComposerClient::Command::SELECT_DISPLAY:
554 return parseSelectDisplay(length);
555 case IComposerClient::Command::SELECT_LAYER:
556 return parseSelectLayer(length);
557 case IComposerClient::Command::SET_COLOR_TRANSFORM:
558 return parseSetColorTransform(length);
559 case IComposerClient::Command::SET_CLIENT_TARGET:
560 return parseSetClientTarget(length);
561 case IComposerClient::Command::SET_OUTPUT_BUFFER:
562 return parseSetOutputBuffer(length);
563 case IComposerClient::Command::VALIDATE_DISPLAY:
564 return parseValidateDisplay(length);
Fabien Sanglard11ec3932017-06-19 19:25:31 -0700565 case IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY:
566 return parsePresentOrValidateDisplay(length);
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500567 case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
568 return parseAcceptDisplayChanges(length);
569 case IComposerClient::Command::PRESENT_DISPLAY:
570 return parsePresentDisplay(length);
571 case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
572 return parseSetLayerCursorPosition(length);
573 case IComposerClient::Command::SET_LAYER_BUFFER:
574 return parseSetLayerBuffer(length);
575 case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
576 return parseSetLayerSurfaceDamage(length);
577 case IComposerClient::Command::SET_LAYER_BLEND_MODE:
578 return parseSetLayerBlendMode(length);
579 case IComposerClient::Command::SET_LAYER_COLOR:
580 return parseSetLayerColor(length);
581 case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
582 return parseSetLayerCompositionType(length);
583 case IComposerClient::Command::SET_LAYER_DATASPACE:
584 return parseSetLayerDataspace(length);
585 case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
586 return parseSetLayerDisplayFrame(length);
587 case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
588 return parseSetLayerPlaneAlpha(length);
589 case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
590 return parseSetLayerSidebandStream(length);
591 case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
592 return parseSetLayerSourceCrop(length);
593 case IComposerClient::Command::SET_LAYER_TRANSFORM:
594 return parseSetLayerTransform(length);
595 case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
596 return parseSetLayerVisibleRegion(length);
597 case IComposerClient::Command::SET_LAYER_Z_ORDER:
598 return parseSetLayerZOrder(length);
599 default:
600 return false;
601 }
602}
603
604bool ComposerClient::CommandReader::parseSelectDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800605{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500606 if (length != CommandWriterBase::kSelectDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800607 return false;
608 }
609
610 mDisplay = read64();
611 mWriter.selectDisplay(mDisplay);
612
613 return true;
614}
615
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500616bool ComposerClient::CommandReader::parseSelectLayer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800617{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500618 if (length != CommandWriterBase::kSelectLayerLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800619 return false;
620 }
621
622 mLayer = read64();
623
624 return true;
625}
626
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500627bool ComposerClient::CommandReader::parseSetColorTransform(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800628{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500629 if (length != CommandWriterBase::kSetColorTransformLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800630 return false;
631 }
632
633 float matrix[16];
634 for (int i = 0; i < 16; i++) {
635 matrix[i] = readFloat();
636 }
637 auto transform = readSigned();
638
639 auto err = mHal.setColorTransform(mDisplay, matrix, transform);
640 if (err != Error::NONE) {
641 mWriter.setError(getCommandLoc(), err);
642 }
643
644 return true;
645}
646
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500647bool ComposerClient::CommandReader::parseSetClientTarget(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800648{
649 // 4 parameters followed by N rectangles
650 if ((length - 4) % 4 != 0) {
651 return false;
652 }
653
Chia-I Wue1768352016-12-19 12:56:54 +0800654 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800655 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800656 auto clientTarget = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800657 auto fence = readFence();
658 auto dataspace = readSigned();
659 auto damage = readRegion((length - 4) / 4);
Steven Thomas58da77e2017-04-26 15:24:28 -0700660 bool closeFence = true;
Chia-I Wubb61a722016-10-24 15:40:20 +0800661
662 auto err = lookupBuffer(BufferCache::CLIENT_TARGETS,
Chia-I Wu41a1c152017-03-09 15:41:59 -0800663 slot, useCache, clientTarget, &clientTarget);
Chia-I Wubb61a722016-10-24 15:40:20 +0800664 if (err == Error::NONE) {
665 err = mHal.setClientTarget(mDisplay, clientTarget, fence,
666 dataspace, damage);
Steven Thomas58da77e2017-04-26 15:24:28 -0700667 auto updateBufErr = updateBuffer(BufferCache::CLIENT_TARGETS, slot,
668 useCache, clientTarget);
669 if (err == Error::NONE) {
670 closeFence = false;
671 err = updateBufErr;
672 }
673 }
674 if (closeFence) {
675 close(fence);
Chia-I Wubb61a722016-10-24 15:40:20 +0800676 }
677 if (err != Error::NONE) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800678 mWriter.setError(getCommandLoc(), err);
679 }
680
681 return true;
682}
683
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500684bool ComposerClient::CommandReader::parseSetOutputBuffer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800685{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500686 if (length != CommandWriterBase::kSetOutputBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800687 return false;
688 }
689
Chia-I Wue1768352016-12-19 12:56:54 +0800690 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800691 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800692 auto outputBuffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800693 auto fence = readFence();
Steven Thomas58da77e2017-04-26 15:24:28 -0700694 bool closeFence = true;
Chia-I Wubb61a722016-10-24 15:40:20 +0800695
696 auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS,
Chia-I Wu41a1c152017-03-09 15:41:59 -0800697 slot, useCache, outputBuffer, &outputBuffer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800698 if (err == Error::NONE) {
699 err = mHal.setOutputBuffer(mDisplay, outputBuffer, fence);
Steven Thomas58da77e2017-04-26 15:24:28 -0700700 auto updateBufErr = updateBuffer(BufferCache::OUTPUT_BUFFERS,
701 slot, useCache, outputBuffer);
702 if (err == Error::NONE) {
703 closeFence = false;
704 err = updateBufErr;
705 }
706 }
707 if (closeFence) {
708 close(fence);
Chia-I Wubb61a722016-10-24 15:40:20 +0800709 }
710 if (err != Error::NONE) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800711 mWriter.setError(getCommandLoc(), err);
712 }
713
714 return true;
715}
716
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500717bool ComposerClient::CommandReader::parseValidateDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800718{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500719 if (length != CommandWriterBase::kValidateDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800720 return false;
721 }
722
723 std::vector<Layer> changedLayers;
724 std::vector<IComposerClient::Composition> compositionTypes;
Chia-I Wue1768352016-12-19 12:56:54 +0800725 uint32_t displayRequestMask = 0x0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800726 std::vector<Layer> requestedLayers;
727 std::vector<uint32_t> requestMasks;
728
Chia-I Wue1768352016-12-19 12:56:54 +0800729 auto err = mHal.validateDisplay(mDisplay, &changedLayers,
730 &compositionTypes, &displayRequestMask,
731 &requestedLayers, &requestMasks);
Chia-I Wubb61a722016-10-24 15:40:20 +0800732 if (err == Error::NONE) {
733 mWriter.setChangedCompositionTypes(changedLayers,
734 compositionTypes);
735 mWriter.setDisplayRequests(displayRequestMask,
736 requestedLayers, requestMasks);
737 } else {
738 mWriter.setError(getCommandLoc(), err);
739 }
740
741 return true;
742}
743
Fabien Sanglard11ec3932017-06-19 19:25:31 -0700744bool ComposerClient::CommandReader::parsePresentOrValidateDisplay(uint16_t length)
745{
746 if (length != CommandWriterBase::kPresentOrValidateDisplayLength) {
747 return false;
748 }
749
750 // First try to Present as is.
751 int presentFence = -1;
752 std::vector<Layer> layers;
753 std::vector<int> fences;
754 auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
755 if (err == Error::NONE) {
756 mWriter.setPresentOrValidateResult(1);
757 mWriter.setPresentFence(presentFence);
758 mWriter.setReleaseFences(layers, fences);
759 return true;
760 }
761
762 // Present has failed. We need to fallback to validate
763 std::vector<Layer> changedLayers;
764 std::vector<IComposerClient::Composition> compositionTypes;
765 uint32_t displayRequestMask = 0x0;
766 std::vector<Layer> requestedLayers;
767 std::vector<uint32_t> requestMasks;
768
769 err = mHal.validateDisplay(mDisplay, &changedLayers,
770 &compositionTypes, &displayRequestMask,
771 &requestedLayers, &requestMasks);
772 if (err == Error::NONE) {
773 mWriter.setPresentOrValidateResult(0);
774 mWriter.setChangedCompositionTypes(changedLayers,
775 compositionTypes);
776 mWriter.setDisplayRequests(displayRequestMask,
777 requestedLayers, requestMasks);
778 } else {
779 mWriter.setError(getCommandLoc(), err);
780 }
781
782 return true;
783}
784
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500785bool ComposerClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800786{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500787 if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800788 return false;
789 }
790
791 auto err = mHal.acceptDisplayChanges(mDisplay);
792 if (err != Error::NONE) {
793 mWriter.setError(getCommandLoc(), err);
794 }
795
796 return true;
797}
798
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500799bool ComposerClient::CommandReader::parsePresentDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800800{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500801 if (length != CommandWriterBase::kPresentDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800802 return false;
803 }
804
Chia-I Wue1768352016-12-19 12:56:54 +0800805 int presentFence = -1;
Chia-I Wubb61a722016-10-24 15:40:20 +0800806 std::vector<Layer> layers;
807 std::vector<int> fences;
Chia-I Wue1768352016-12-19 12:56:54 +0800808 auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
Chia-I Wubb61a722016-10-24 15:40:20 +0800809 if (err == Error::NONE) {
810 mWriter.setPresentFence(presentFence);
811 mWriter.setReleaseFences(layers, fences);
812 } else {
813 mWriter.setError(getCommandLoc(), err);
814 }
815
816 return true;
817}
818
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500819bool ComposerClient::CommandReader::parseSetLayerCursorPosition(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800820{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500821 if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800822 return false;
823 }
824
825 auto err = mHal.setLayerCursorPosition(mDisplay, mLayer,
826 readSigned(), readSigned());
827 if (err != Error::NONE) {
828 mWriter.setError(getCommandLoc(), err);
829 }
830
831 return true;
832}
833
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500834bool ComposerClient::CommandReader::parseSetLayerBuffer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800835{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500836 if (length != CommandWriterBase::kSetLayerBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800837 return false;
838 }
839
Chia-I Wue1768352016-12-19 12:56:54 +0800840 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800841 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800842 auto buffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800843 auto fence = readFence();
Steven Thomas58da77e2017-04-26 15:24:28 -0700844 bool closeFence = true;
Chia-I Wubb61a722016-10-24 15:40:20 +0800845
846 auto err = lookupBuffer(BufferCache::LAYER_BUFFERS,
Chia-I Wu41a1c152017-03-09 15:41:59 -0800847 slot, useCache, buffer, &buffer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800848 if (err == Error::NONE) {
849 err = mHal.setLayerBuffer(mDisplay, mLayer, buffer, fence);
Steven Thomas58da77e2017-04-26 15:24:28 -0700850 auto updateBufErr = updateBuffer(BufferCache::LAYER_BUFFERS, slot,
851 useCache, buffer);
852 if (err == Error::NONE) {
853 closeFence = false;
854 err = updateBufErr;
855 }
856 }
857 if (closeFence) {
858 close(fence);
Chia-I Wubb61a722016-10-24 15:40:20 +0800859 }
860 if (err != Error::NONE) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800861 mWriter.setError(getCommandLoc(), err);
862 }
863
864 return true;
865}
866
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500867bool ComposerClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800868{
869 // N rectangles
870 if (length % 4 != 0) {
871 return false;
872 }
873
874 auto damage = readRegion(length / 4);
875 auto err = mHal.setLayerSurfaceDamage(mDisplay, mLayer, damage);
876 if (err != Error::NONE) {
877 mWriter.setError(getCommandLoc(), err);
878 }
879
880 return true;
881}
882
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500883bool ComposerClient::CommandReader::parseSetLayerBlendMode(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800884{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500885 if (length != CommandWriterBase::kSetLayerBlendModeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800886 return false;
887 }
888
889 auto err = mHal.setLayerBlendMode(mDisplay, mLayer, readSigned());
890 if (err != Error::NONE) {
891 mWriter.setError(getCommandLoc(), err);
892 }
893
894 return true;
895}
896
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500897bool ComposerClient::CommandReader::parseSetLayerColor(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800898{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500899 if (length != CommandWriterBase::kSetLayerColorLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800900 return false;
901 }
902
903 auto err = mHal.setLayerColor(mDisplay, mLayer, readColor());
904 if (err != Error::NONE) {
905 mWriter.setError(getCommandLoc(), err);
906 }
907
908 return true;
909}
910
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500911bool ComposerClient::CommandReader::parseSetLayerCompositionType(
912 uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800913{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500914 if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800915 return false;
916 }
917
918 auto err = mHal.setLayerCompositionType(mDisplay, mLayer, readSigned());
919 if (err != Error::NONE) {
920 mWriter.setError(getCommandLoc(), err);
921 }
922
923 return true;
924}
925
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500926bool ComposerClient::CommandReader::parseSetLayerDataspace(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800927{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500928 if (length != CommandWriterBase::kSetLayerDataspaceLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800929 return false;
930 }
931
932 auto err = mHal.setLayerDataspace(mDisplay, mLayer, readSigned());
933 if (err != Error::NONE) {
934 mWriter.setError(getCommandLoc(), err);
935 }
936
937 return true;
938}
939
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500940bool ComposerClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800941{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500942 if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800943 return false;
944 }
945
946 auto err = mHal.setLayerDisplayFrame(mDisplay, mLayer, readRect());
947 if (err != Error::NONE) {
948 mWriter.setError(getCommandLoc(), err);
949 }
950
951 return true;
952}
953
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500954bool ComposerClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800955{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500956 if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800957 return false;
958 }
959
Dan Stoza0df10c42016-12-19 15:22:47 -0800960 auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
Chia-I Wubb61a722016-10-24 15:40:20 +0800961 if (err != Error::NONE) {
962 mWriter.setError(getCommandLoc(), err);
963 }
964
965 return true;
966}
967
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500968bool ComposerClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800969{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500970 if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800971 return false;
972 }
973
974 auto stream = readHandle();
975
Chia-I Wu41a1c152017-03-09 15:41:59 -0800976 auto err = lookupLayerSidebandStream(stream, &stream);
Chia-I Wubb61a722016-10-24 15:40:20 +0800977 if (err == Error::NONE) {
978 err = mHal.setLayerSidebandStream(mDisplay, mLayer, stream);
Steven Thomas58da77e2017-04-26 15:24:28 -0700979 auto updateErr = updateLayerSidebandStream(stream);
980 if (err == Error::NONE) {
981 err = updateErr;
982 }
Chia-I Wubb61a722016-10-24 15:40:20 +0800983 }
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::parseSetLayerSourceCrop(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800992{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500993 if (length != CommandWriterBase::kSetLayerSourceCropLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800994 return false;
995 }
996
997 auto err = mHal.setLayerSourceCrop(mDisplay, mLayer, readFRect());
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::parseSetLayerTransform(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +08001006{
Daniel Nicoarabd82b812017-01-17 11:15:26 -05001007 if (length != CommandWriterBase::kSetLayerTransformLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +08001008 return false;
1009 }
1010
1011 auto err = mHal.setLayerTransform(mDisplay, mLayer, readSigned());
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::parseSetLayerVisibleRegion(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +08001020{
1021 // N rectangles
1022 if (length % 4 != 0) {
1023 return false;
1024 }
1025
1026 auto region = readRegion(length / 4);
1027 auto err = mHal.setLayerVisibleRegion(mDisplay, mLayer, region);
1028 if (err != Error::NONE) {
1029 mWriter.setError(getCommandLoc(), err);
1030 }
1031
1032 return true;
1033}
1034
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001035bool ComposerClient::CommandReader::parseSetLayerZOrder(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +08001036{
Daniel Nicoarabd82b812017-01-17 11:15:26 -05001037 if (length != CommandWriterBase::kSetLayerZOrderLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +08001038 return false;
1039 }
1040
1041 auto err = mHal.setLayerZOrder(mDisplay, mLayer, read());
1042 if (err != Error::NONE) {
1043 mWriter.setError(getCommandLoc(), err);
1044 }
1045
1046 return true;
1047}
1048
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001049hwc_rect_t ComposerClient::CommandReader::readRect()
Chia-I Wubb61a722016-10-24 15:40:20 +08001050{
1051 return hwc_rect_t{
1052 readSigned(),
1053 readSigned(),
1054 readSigned(),
1055 readSigned(),
1056 };
1057}
1058
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001059std::vector<hwc_rect_t> ComposerClient::CommandReader::readRegion(size_t count)
Chia-I Wubb61a722016-10-24 15:40:20 +08001060{
1061 std::vector<hwc_rect_t> region;
1062 region.reserve(count);
1063 while (count > 0) {
1064 region.emplace_back(readRect());
1065 count--;
1066 }
1067
1068 return region;
1069}
1070
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001071hwc_frect_t ComposerClient::CommandReader::readFRect()
Chia-I Wubb61a722016-10-24 15:40:20 +08001072{
1073 return hwc_frect_t{
1074 readFloat(),
1075 readFloat(),
1076 readFloat(),
1077 readFloat(),
1078 };
1079}
1080
Chia-I Wu41a1c152017-03-09 15:41:59 -08001081Error ComposerClient::CommandReader::lookupBufferCacheEntryLocked(
1082 BufferCache cache, uint32_t slot, BufferCacheEntry** outEntry)
Chia-I Wubb61a722016-10-24 15:40:20 +08001083{
Chia-I Wubb61a722016-10-24 15:40:20 +08001084 auto dpy = mClient.mDisplayData.find(mDisplay);
1085 if (dpy == mClient.mDisplayData.end()) {
1086 return Error::BAD_DISPLAY;
1087 }
1088
Chia-I Wu41a1c152017-03-09 15:41:59 -08001089 BufferCacheEntry* entry = nullptr;
Chia-I Wubb61a722016-10-24 15:40:20 +08001090 switch (cache) {
1091 case BufferCache::CLIENT_TARGETS:
1092 if (slot < dpy->second.ClientTargets.size()) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001093 entry = &dpy->second.ClientTargets[slot];
Chia-I Wubb61a722016-10-24 15:40:20 +08001094 }
1095 break;
1096 case BufferCache::OUTPUT_BUFFERS:
1097 if (slot < dpy->second.OutputBuffers.size()) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001098 entry = &dpy->second.OutputBuffers[slot];
Chia-I Wubb61a722016-10-24 15:40:20 +08001099 }
1100 break;
1101 case BufferCache::LAYER_BUFFERS:
1102 {
1103 auto ly = dpy->second.Layers.find(mLayer);
1104 if (ly == dpy->second.Layers.end()) {
1105 return Error::BAD_LAYER;
1106 }
1107 if (slot < ly->second.Buffers.size()) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001108 entry = &ly->second.Buffers[slot];
Chia-I Wubb61a722016-10-24 15:40:20 +08001109 }
1110 }
1111 break;
1112 case BufferCache::LAYER_SIDEBAND_STREAMS:
1113 {
1114 auto ly = dpy->second.Layers.find(mLayer);
1115 if (ly == dpy->second.Layers.end()) {
1116 return Error::BAD_LAYER;
1117 }
1118 if (slot == 0) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001119 entry = &ly->second.SidebandStream;
Chia-I Wubb61a722016-10-24 15:40:20 +08001120 }
1121 }
1122 break;
1123 default:
1124 break;
1125 }
1126
Chia-I Wu41a1c152017-03-09 15:41:59 -08001127 if (!entry) {
1128 ALOGW("invalid buffer slot %" PRIu32, slot);
Chia-I Wubb61a722016-10-24 15:40:20 +08001129 return Error::BAD_PARAMETER;
1130 }
1131
Chia-I Wu41a1c152017-03-09 15:41:59 -08001132 *outEntry = entry;
1133
1134 return Error::NONE;
1135}
1136
1137Error ComposerClient::CommandReader::lookupBuffer(BufferCache cache,
1138 uint32_t slot, bool useCache, buffer_handle_t handle,
1139 buffer_handle_t* outHandle)
1140{
Chia-I Wubb61a722016-10-24 15:40:20 +08001141 if (useCache) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001142 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1143
1144 BufferCacheEntry* entry;
1145 Error error = lookupBufferCacheEntryLocked(cache, slot, &entry);
1146 if (error != Error::NONE) {
1147 return error;
1148 }
1149
1150 // input handle is ignored
1151 *outHandle = entry->getHandle();
Chia-I Wubb61a722016-10-24 15:40:20 +08001152 } else {
1153 if (!sHandleImporter.importBuffer(handle)) {
1154 return Error::NO_RESOURCES;
1155 }
1156
Chia-I Wu41a1c152017-03-09 15:41:59 -08001157 *outHandle = handle;
Chia-I Wubb61a722016-10-24 15:40:20 +08001158 }
1159
1160 return Error::NONE;
1161}
1162
Steven Thomas58da77e2017-04-26 15:24:28 -07001163Error ComposerClient::CommandReader::updateBuffer(BufferCache cache,
Chia-I Wu41a1c152017-03-09 15:41:59 -08001164 uint32_t slot, bool useCache, buffer_handle_t handle)
1165{
1166 // handle was looked up from cache
1167 if (useCache) {
Steven Thomas58da77e2017-04-26 15:24:28 -07001168 return Error::NONE;
Chia-I Wu41a1c152017-03-09 15:41:59 -08001169 }
1170
1171 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1172
1173 BufferCacheEntry* entry = nullptr;
Steven Thomas58da77e2017-04-26 15:24:28 -07001174 Error error = lookupBufferCacheEntryLocked(cache, slot, &entry);
1175 if (error != Error::NONE) {
1176 return error;
1177 }
Chia-I Wu41a1c152017-03-09 15:41:59 -08001178
1179 *entry = handle;
Steven Thomas58da77e2017-04-26 15:24:28 -07001180 return Error::NONE;
Chia-I Wu41a1c152017-03-09 15:41:59 -08001181}
1182
Chia-I Wubb61a722016-10-24 15:40:20 +08001183} // namespace implementation
1184} // namespace V2_1
1185} // namespace composer
1186} // namespace graphics
1187} // namespace hardware
1188} // namespace android