blob: 87e4d3b7a7df1d39e063e31a5043f52df281cefe [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);
565 case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
566 return parseAcceptDisplayChanges(length);
567 case IComposerClient::Command::PRESENT_DISPLAY:
568 return parsePresentDisplay(length);
569 case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
570 return parseSetLayerCursorPosition(length);
571 case IComposerClient::Command::SET_LAYER_BUFFER:
572 return parseSetLayerBuffer(length);
573 case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
574 return parseSetLayerSurfaceDamage(length);
575 case IComposerClient::Command::SET_LAYER_BLEND_MODE:
576 return parseSetLayerBlendMode(length);
577 case IComposerClient::Command::SET_LAYER_COLOR:
578 return parseSetLayerColor(length);
579 case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
580 return parseSetLayerCompositionType(length);
581 case IComposerClient::Command::SET_LAYER_DATASPACE:
582 return parseSetLayerDataspace(length);
583 case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
584 return parseSetLayerDisplayFrame(length);
585 case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
586 return parseSetLayerPlaneAlpha(length);
587 case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
588 return parseSetLayerSidebandStream(length);
589 case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
590 return parseSetLayerSourceCrop(length);
591 case IComposerClient::Command::SET_LAYER_TRANSFORM:
592 return parseSetLayerTransform(length);
593 case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
594 return parseSetLayerVisibleRegion(length);
595 case IComposerClient::Command::SET_LAYER_Z_ORDER:
596 return parseSetLayerZOrder(length);
597 default:
598 return false;
599 }
600}
601
602bool ComposerClient::CommandReader::parseSelectDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800603{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500604 if (length != CommandWriterBase::kSelectDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800605 return false;
606 }
607
608 mDisplay = read64();
609 mWriter.selectDisplay(mDisplay);
610
611 return true;
612}
613
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500614bool ComposerClient::CommandReader::parseSelectLayer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800615{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500616 if (length != CommandWriterBase::kSelectLayerLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800617 return false;
618 }
619
620 mLayer = read64();
621
622 return true;
623}
624
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500625bool ComposerClient::CommandReader::parseSetColorTransform(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800626{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500627 if (length != CommandWriterBase::kSetColorTransformLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800628 return false;
629 }
630
631 float matrix[16];
632 for (int i = 0; i < 16; i++) {
633 matrix[i] = readFloat();
634 }
635 auto transform = readSigned();
636
637 auto err = mHal.setColorTransform(mDisplay, matrix, transform);
638 if (err != Error::NONE) {
639 mWriter.setError(getCommandLoc(), err);
640 }
641
642 return true;
643}
644
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500645bool ComposerClient::CommandReader::parseSetClientTarget(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800646{
647 // 4 parameters followed by N rectangles
648 if ((length - 4) % 4 != 0) {
649 return false;
650 }
651
Chia-I Wue1768352016-12-19 12:56:54 +0800652 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800653 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800654 auto clientTarget = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800655 auto fence = readFence();
656 auto dataspace = readSigned();
657 auto damage = readRegion((length - 4) / 4);
658
659 auto err = lookupBuffer(BufferCache::CLIENT_TARGETS,
Chia-I Wu41a1c152017-03-09 15:41:59 -0800660 slot, useCache, clientTarget, &clientTarget);
Chia-I Wubb61a722016-10-24 15:40:20 +0800661 if (err == Error::NONE) {
662 err = mHal.setClientTarget(mDisplay, clientTarget, fence,
663 dataspace, damage);
Chia-I Wu41a1c152017-03-09 15:41:59 -0800664
665 updateBuffer(BufferCache::CLIENT_TARGETS, slot, useCache,
666 clientTarget);
Chia-I Wubb61a722016-10-24 15:40:20 +0800667 }
668 if (err != Error::NONE) {
669 close(fence);
670 mWriter.setError(getCommandLoc(), err);
671 }
672
673 return true;
674}
675
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500676bool ComposerClient::CommandReader::parseSetOutputBuffer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800677{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500678 if (length != CommandWriterBase::kSetOutputBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800679 return false;
680 }
681
Chia-I Wue1768352016-12-19 12:56:54 +0800682 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800683 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800684 auto outputBuffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800685 auto fence = readFence();
686
687 auto err = lookupBuffer(BufferCache::OUTPUT_BUFFERS,
Chia-I Wu41a1c152017-03-09 15:41:59 -0800688 slot, useCache, outputBuffer, &outputBuffer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800689 if (err == Error::NONE) {
690 err = mHal.setOutputBuffer(mDisplay, outputBuffer, fence);
Chia-I Wu41a1c152017-03-09 15:41:59 -0800691
692 updateBuffer(BufferCache::OUTPUT_BUFFERS,
693 slot, useCache, outputBuffer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800694 }
695 if (err != Error::NONE) {
696 close(fence);
697 mWriter.setError(getCommandLoc(), err);
698 }
699
700 return true;
701}
702
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500703bool ComposerClient::CommandReader::parseValidateDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800704{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500705 if (length != CommandWriterBase::kValidateDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800706 return false;
707 }
708
709 std::vector<Layer> changedLayers;
710 std::vector<IComposerClient::Composition> compositionTypes;
Chia-I Wue1768352016-12-19 12:56:54 +0800711 uint32_t displayRequestMask = 0x0;
Chia-I Wubb61a722016-10-24 15:40:20 +0800712 std::vector<Layer> requestedLayers;
713 std::vector<uint32_t> requestMasks;
714
Chia-I Wue1768352016-12-19 12:56:54 +0800715 auto err = mHal.validateDisplay(mDisplay, &changedLayers,
716 &compositionTypes, &displayRequestMask,
717 &requestedLayers, &requestMasks);
Chia-I Wubb61a722016-10-24 15:40:20 +0800718 if (err == Error::NONE) {
719 mWriter.setChangedCompositionTypes(changedLayers,
720 compositionTypes);
721 mWriter.setDisplayRequests(displayRequestMask,
722 requestedLayers, requestMasks);
723 } else {
724 mWriter.setError(getCommandLoc(), err);
725 }
726
727 return true;
728}
729
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500730bool ComposerClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800731{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500732 if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800733 return false;
734 }
735
736 auto err = mHal.acceptDisplayChanges(mDisplay);
737 if (err != Error::NONE) {
738 mWriter.setError(getCommandLoc(), err);
739 }
740
741 return true;
742}
743
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500744bool ComposerClient::CommandReader::parsePresentDisplay(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800745{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500746 if (length != CommandWriterBase::kPresentDisplayLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800747 return false;
748 }
749
Chia-I Wue1768352016-12-19 12:56:54 +0800750 int presentFence = -1;
Chia-I Wubb61a722016-10-24 15:40:20 +0800751 std::vector<Layer> layers;
752 std::vector<int> fences;
Chia-I Wue1768352016-12-19 12:56:54 +0800753 auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
Chia-I Wubb61a722016-10-24 15:40:20 +0800754 if (err == Error::NONE) {
755 mWriter.setPresentFence(presentFence);
756 mWriter.setReleaseFences(layers, fences);
757 } else {
758 mWriter.setError(getCommandLoc(), err);
759 }
760
761 return true;
762}
763
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500764bool ComposerClient::CommandReader::parseSetLayerCursorPosition(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800765{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500766 if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800767 return false;
768 }
769
770 auto err = mHal.setLayerCursorPosition(mDisplay, mLayer,
771 readSigned(), readSigned());
772 if (err != Error::NONE) {
773 mWriter.setError(getCommandLoc(), err);
774 }
775
776 return true;
777}
778
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500779bool ComposerClient::CommandReader::parseSetLayerBuffer(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800780{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500781 if (length != CommandWriterBase::kSetLayerBufferLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800782 return false;
783 }
784
Chia-I Wue1768352016-12-19 12:56:54 +0800785 bool useCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800786 auto slot = read();
Chia-I Wue1768352016-12-19 12:56:54 +0800787 auto buffer = readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800788 auto fence = readFence();
789
790 auto err = lookupBuffer(BufferCache::LAYER_BUFFERS,
Chia-I Wu41a1c152017-03-09 15:41:59 -0800791 slot, useCache, buffer, &buffer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800792 if (err == Error::NONE) {
793 err = mHal.setLayerBuffer(mDisplay, mLayer, buffer, fence);
Chia-I Wu41a1c152017-03-09 15:41:59 -0800794
795 updateBuffer(BufferCache::LAYER_BUFFERS,
796 slot, useCache, buffer);
Chia-I Wubb61a722016-10-24 15:40:20 +0800797 }
798 if (err != Error::NONE) {
799 close(fence);
800 mWriter.setError(getCommandLoc(), err);
801 }
802
803 return true;
804}
805
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500806bool ComposerClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800807{
808 // N rectangles
809 if (length % 4 != 0) {
810 return false;
811 }
812
813 auto damage = readRegion(length / 4);
814 auto err = mHal.setLayerSurfaceDamage(mDisplay, mLayer, damage);
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::parseSetLayerBlendMode(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800823{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500824 if (length != CommandWriterBase::kSetLayerBlendModeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800825 return false;
826 }
827
828 auto err = mHal.setLayerBlendMode(mDisplay, mLayer, readSigned());
829 if (err != Error::NONE) {
830 mWriter.setError(getCommandLoc(), err);
831 }
832
833 return true;
834}
835
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500836bool ComposerClient::CommandReader::parseSetLayerColor(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800837{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500838 if (length != CommandWriterBase::kSetLayerColorLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800839 return false;
840 }
841
842 auto err = mHal.setLayerColor(mDisplay, mLayer, readColor());
843 if (err != Error::NONE) {
844 mWriter.setError(getCommandLoc(), err);
845 }
846
847 return true;
848}
849
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500850bool ComposerClient::CommandReader::parseSetLayerCompositionType(
851 uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800852{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500853 if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800854 return false;
855 }
856
857 auto err = mHal.setLayerCompositionType(mDisplay, mLayer, readSigned());
858 if (err != Error::NONE) {
859 mWriter.setError(getCommandLoc(), err);
860 }
861
862 return true;
863}
864
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500865bool ComposerClient::CommandReader::parseSetLayerDataspace(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800866{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500867 if (length != CommandWriterBase::kSetLayerDataspaceLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800868 return false;
869 }
870
871 auto err = mHal.setLayerDataspace(mDisplay, mLayer, readSigned());
872 if (err != Error::NONE) {
873 mWriter.setError(getCommandLoc(), err);
874 }
875
876 return true;
877}
878
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500879bool ComposerClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800880{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500881 if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800882 return false;
883 }
884
885 auto err = mHal.setLayerDisplayFrame(mDisplay, mLayer, readRect());
886 if (err != Error::NONE) {
887 mWriter.setError(getCommandLoc(), err);
888 }
889
890 return true;
891}
892
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500893bool ComposerClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800894{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500895 if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800896 return false;
897 }
898
Dan Stoza0df10c42016-12-19 15:22:47 -0800899 auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
Chia-I Wubb61a722016-10-24 15:40:20 +0800900 if (err != Error::NONE) {
901 mWriter.setError(getCommandLoc(), err);
902 }
903
904 return true;
905}
906
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500907bool ComposerClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800908{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500909 if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800910 return false;
911 }
912
913 auto stream = readHandle();
914
Chia-I Wu41a1c152017-03-09 15:41:59 -0800915 auto err = lookupLayerSidebandStream(stream, &stream);
Chia-I Wubb61a722016-10-24 15:40:20 +0800916 if (err == Error::NONE) {
917 err = mHal.setLayerSidebandStream(mDisplay, mLayer, stream);
Chia-I Wu41a1c152017-03-09 15:41:59 -0800918
919 updateLayerSidebandStream(stream);
Chia-I Wubb61a722016-10-24 15:40:20 +0800920 }
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::parseSetLayerSourceCrop(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800929{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500930 if (length != CommandWriterBase::kSetLayerSourceCropLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800931 return false;
932 }
933
934 auto err = mHal.setLayerSourceCrop(mDisplay, mLayer, readFRect());
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::parseSetLayerTransform(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800943{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500944 if (length != CommandWriterBase::kSetLayerTransformLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800945 return false;
946 }
947
948 auto err = mHal.setLayerTransform(mDisplay, mLayer, readSigned());
949 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::parseSetLayerVisibleRegion(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800957{
958 // N rectangles
959 if (length % 4 != 0) {
960 return false;
961 }
962
963 auto region = readRegion(length / 4);
964 auto err = mHal.setLayerVisibleRegion(mDisplay, mLayer, region);
965 if (err != Error::NONE) {
966 mWriter.setError(getCommandLoc(), err);
967 }
968
969 return true;
970}
971
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500972bool ComposerClient::CommandReader::parseSetLayerZOrder(uint16_t length)
Chia-I Wubb61a722016-10-24 15:40:20 +0800973{
Daniel Nicoarabd82b812017-01-17 11:15:26 -0500974 if (length != CommandWriterBase::kSetLayerZOrderLength) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800975 return false;
976 }
977
978 auto err = mHal.setLayerZOrder(mDisplay, mLayer, read());
979 if (err != Error::NONE) {
980 mWriter.setError(getCommandLoc(), err);
981 }
982
983 return true;
984}
985
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500986hwc_rect_t ComposerClient::CommandReader::readRect()
Chia-I Wubb61a722016-10-24 15:40:20 +0800987{
988 return hwc_rect_t{
989 readSigned(),
990 readSigned(),
991 readSigned(),
992 readSigned(),
993 };
994}
995
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -0500996std::vector<hwc_rect_t> ComposerClient::CommandReader::readRegion(size_t count)
Chia-I Wubb61a722016-10-24 15:40:20 +0800997{
998 std::vector<hwc_rect_t> region;
999 region.reserve(count);
1000 while (count > 0) {
1001 region.emplace_back(readRect());
1002 count--;
1003 }
1004
1005 return region;
1006}
1007
Daniel Nicoara0a60e4b2017-01-09 12:51:06 -05001008hwc_frect_t ComposerClient::CommandReader::readFRect()
Chia-I Wubb61a722016-10-24 15:40:20 +08001009{
1010 return hwc_frect_t{
1011 readFloat(),
1012 readFloat(),
1013 readFloat(),
1014 readFloat(),
1015 };
1016}
1017
Chia-I Wu41a1c152017-03-09 15:41:59 -08001018Error ComposerClient::CommandReader::lookupBufferCacheEntryLocked(
1019 BufferCache cache, uint32_t slot, BufferCacheEntry** outEntry)
Chia-I Wubb61a722016-10-24 15:40:20 +08001020{
Chia-I Wubb61a722016-10-24 15:40:20 +08001021 auto dpy = mClient.mDisplayData.find(mDisplay);
1022 if (dpy == mClient.mDisplayData.end()) {
1023 return Error::BAD_DISPLAY;
1024 }
1025
Chia-I Wu41a1c152017-03-09 15:41:59 -08001026 BufferCacheEntry* entry = nullptr;
Chia-I Wubb61a722016-10-24 15:40:20 +08001027 switch (cache) {
1028 case BufferCache::CLIENT_TARGETS:
1029 if (slot < dpy->second.ClientTargets.size()) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001030 entry = &dpy->second.ClientTargets[slot];
Chia-I Wubb61a722016-10-24 15:40:20 +08001031 }
1032 break;
1033 case BufferCache::OUTPUT_BUFFERS:
1034 if (slot < dpy->second.OutputBuffers.size()) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001035 entry = &dpy->second.OutputBuffers[slot];
Chia-I Wubb61a722016-10-24 15:40:20 +08001036 }
1037 break;
1038 case BufferCache::LAYER_BUFFERS:
1039 {
1040 auto ly = dpy->second.Layers.find(mLayer);
1041 if (ly == dpy->second.Layers.end()) {
1042 return Error::BAD_LAYER;
1043 }
1044 if (slot < ly->second.Buffers.size()) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001045 entry = &ly->second.Buffers[slot];
Chia-I Wubb61a722016-10-24 15:40:20 +08001046 }
1047 }
1048 break;
1049 case BufferCache::LAYER_SIDEBAND_STREAMS:
1050 {
1051 auto ly = dpy->second.Layers.find(mLayer);
1052 if (ly == dpy->second.Layers.end()) {
1053 return Error::BAD_LAYER;
1054 }
1055 if (slot == 0) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001056 entry = &ly->second.SidebandStream;
Chia-I Wubb61a722016-10-24 15:40:20 +08001057 }
1058 }
1059 break;
1060 default:
1061 break;
1062 }
1063
Chia-I Wu41a1c152017-03-09 15:41:59 -08001064 if (!entry) {
1065 ALOGW("invalid buffer slot %" PRIu32, slot);
Chia-I Wubb61a722016-10-24 15:40:20 +08001066 return Error::BAD_PARAMETER;
1067 }
1068
Chia-I Wu41a1c152017-03-09 15:41:59 -08001069 *outEntry = entry;
1070
1071 return Error::NONE;
1072}
1073
1074Error ComposerClient::CommandReader::lookupBuffer(BufferCache cache,
1075 uint32_t slot, bool useCache, buffer_handle_t handle,
1076 buffer_handle_t* outHandle)
1077{
Chia-I Wubb61a722016-10-24 15:40:20 +08001078 if (useCache) {
Chia-I Wu41a1c152017-03-09 15:41:59 -08001079 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1080
1081 BufferCacheEntry* entry;
1082 Error error = lookupBufferCacheEntryLocked(cache, slot, &entry);
1083 if (error != Error::NONE) {
1084 return error;
1085 }
1086
1087 // input handle is ignored
1088 *outHandle = entry->getHandle();
Chia-I Wubb61a722016-10-24 15:40:20 +08001089 } else {
1090 if (!sHandleImporter.importBuffer(handle)) {
1091 return Error::NO_RESOURCES;
1092 }
1093
Chia-I Wu41a1c152017-03-09 15:41:59 -08001094 *outHandle = handle;
Chia-I Wubb61a722016-10-24 15:40:20 +08001095 }
1096
1097 return Error::NONE;
1098}
1099
Chia-I Wu41a1c152017-03-09 15:41:59 -08001100void ComposerClient::CommandReader::updateBuffer(BufferCache cache,
1101 uint32_t slot, bool useCache, buffer_handle_t handle)
1102{
1103 // handle was looked up from cache
1104 if (useCache) {
1105 return;
1106 }
1107
1108 std::lock_guard<std::mutex> lock(mClient.mDisplayDataMutex);
1109
1110 BufferCacheEntry* entry = nullptr;
1111 lookupBufferCacheEntryLocked(cache, slot, &entry);
1112 LOG_FATAL_IF(!entry, "failed to find the cache entry to update");
1113
1114 *entry = handle;
1115}
1116
Chia-I Wubb61a722016-10-24 15:40:20 +08001117} // namespace implementation
1118} // namespace V2_1
1119} // namespace composer
1120} // namespace graphics
1121} // namespace hardware
1122} // namespace android