1 /*
2 * Copyright (C) 2021 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 #include "ComposerCommandEngine.h"
18
19 #include <hardware/hwcomposer2.h>
20
21 #include <set>
22
23 #include "Util.h"
24
25 namespace aidl::android::hardware::graphics::composer3::impl {
26
27 #define DISPATCH_LAYER_COMMAND(display, layerCmd, field, funcName) \
28 do { \
29 if (layerCmd.field) { \
30 executeSetLayer##funcName(display, layerCmd.layer, *layerCmd.field); \
31 } \
32 } while (0)
33
34 #define DISPATCH_LAYER_COMMAND_SIMPLE(display, layerCmd, field, funcName) \
35 do { \
36 dispatchLayerCommand(display, layerCmd.layer, #field, layerCmd.field, \
37 &IComposerHal::setLayer##funcName); \
38 } while (0)
39
40 #define DISPATCH_DISPLAY_COMMAND(displayCmd, field, funcName) \
41 do { \
42 if (displayCmd.field) { \
43 execute##funcName(displayCmd.display, *displayCmd.field); \
44 } \
45 } while (0)
46
47 #define DISPATCH_DISPLAY_BOOL_COMMAND(displayCmd, field, funcName) \
48 do { \
49 if (displayCmd.field) { \
50 execute##funcName(displayCmd.display); \
51 } \
52 } while (0)
53
54 #define DISPATCH_DISPLAY_BOOL_COMMAND_AND_DATA(displayCmd, field, data, funcName) \
55 do { \
56 if (displayCmd.field) { \
57 execute##funcName(displayCmd.display, displayCmd.data); \
58 } \
59 } while (0)
60
init()61 int32_t ComposerCommandEngine::init() {
62 mWriter = std::make_unique<ComposerServiceWriter>();
63 return (mWriter != nullptr) ? ::android::NO_ERROR : ::android::NO_MEMORY;
64 }
65
execute(const std::vector<DisplayCommand> & commands,std::vector<CommandResultPayload> * result)66 int32_t ComposerCommandEngine::execute(const std::vector<DisplayCommand>& commands,
67 std::vector<CommandResultPayload>* result) {
68 std::set<int64_t> displaysPendingBrightenssChange;
69 mCommandIndex = 0;
70 for (const auto& command : commands) {
71 dispatchDisplayCommand(command);
72 ++mCommandIndex;
73 // The input commands could have 2+ commands for the same display.
74 // If the first has pending brightness change, the second presentDisplay will apply it.
75 if (command.validateDisplay || command.presentDisplay ||
76 command.presentOrValidateDisplay) {
77 displaysPendingBrightenssChange.erase(command.display);
78 } else if (command.brightness) {
79 displaysPendingBrightenssChange.insert(command.display);
80 }
81 }
82
83 *result = mWriter->getPendingCommandResults();
84 mWriter->reset();
85
86 // standalone display brightness command shouldn't wait for next present or validate
87 for (auto display : displaysPendingBrightenssChange) {
88 auto err = mHal->flushDisplayBrightnessChange(display);
89 if (err) {
90 return err;
91 }
92 }
93 return ::android::NO_ERROR;
94 }
95
dispatchDisplayCommand(const DisplayCommand & command)96 void ComposerCommandEngine::dispatchDisplayCommand(const DisplayCommand& command) {
97 // place SetDisplayBrightness before SetLayerWhitePointNits since current
98 // display brightness is used to validate the layer white point nits.
99 DISPATCH_DISPLAY_COMMAND(command, brightness, SetDisplayBrightness);
100 for (const auto& layerCmd : command.layers) {
101 dispatchLayerCommand(command.display, layerCmd);
102 }
103
104 DISPATCH_DISPLAY_COMMAND(command, colorTransformMatrix, SetColorTransform);
105 DISPATCH_DISPLAY_COMMAND(command, clientTarget, SetClientTarget);
106 DISPATCH_DISPLAY_COMMAND(command, virtualDisplayOutputBuffer, SetOutputBuffer);
107 DISPATCH_DISPLAY_BOOL_COMMAND_AND_DATA(command, validateDisplay, expectedPresentTime,
108 ValidateDisplay);
109 DISPATCH_DISPLAY_BOOL_COMMAND(command, acceptDisplayChanges, AcceptDisplayChanges);
110 DISPATCH_DISPLAY_BOOL_COMMAND(command, presentDisplay, PresentDisplay);
111 DISPATCH_DISPLAY_BOOL_COMMAND_AND_DATA(command, presentOrValidateDisplay, expectedPresentTime,
112 PresentOrValidateDisplay);
113 }
114
dispatchLayerCommand(int64_t display,const LayerCommand & command)115 void ComposerCommandEngine::dispatchLayerCommand(int64_t display, const LayerCommand& command) {
116 DISPATCH_LAYER_COMMAND(display, command, cursorPosition, CursorPosition);
117 DISPATCH_LAYER_COMMAND(display, command, buffer, Buffer);
118 DISPATCH_LAYER_COMMAND(display, command, damage, SurfaceDamage);
119 DISPATCH_LAYER_COMMAND(display, command, blendMode, BlendMode);
120 DISPATCH_LAYER_COMMAND(display, command, color, Color);
121 DISPATCH_LAYER_COMMAND(display, command, composition, Composition);
122 DISPATCH_LAYER_COMMAND(display, command, dataspace, Dataspace);
123 DISPATCH_LAYER_COMMAND(display, command, displayFrame, DisplayFrame);
124 DISPATCH_LAYER_COMMAND(display, command, planeAlpha, PlaneAlpha);
125 DISPATCH_LAYER_COMMAND(display, command, sidebandStream, SidebandStream);
126 DISPATCH_LAYER_COMMAND(display, command, sourceCrop, SourceCrop);
127 DISPATCH_LAYER_COMMAND(display, command, transform, Transform);
128 DISPATCH_LAYER_COMMAND(display, command, visibleRegion, VisibleRegion);
129 DISPATCH_LAYER_COMMAND(display, command, z, ZOrder);
130 DISPATCH_LAYER_COMMAND(display, command, colorTransform, ColorTransform);
131 DISPATCH_LAYER_COMMAND(display, command, brightness, Brightness);
132 DISPATCH_LAYER_COMMAND(display, command, perFrameMetadata, PerFrameMetadata);
133 DISPATCH_LAYER_COMMAND(display, command, perFrameMetadataBlob, PerFrameMetadataBlobs);
134 DISPATCH_LAYER_COMMAND_SIMPLE(display, command, blockingRegion, BlockingRegion);
135 }
136
executeValidateDisplayInternal(int64_t display)137 int32_t ComposerCommandEngine::executeValidateDisplayInternal(int64_t display) {
138 std::vector<int64_t> changedLayers;
139 std::vector<Composition> compositionTypes;
140 uint32_t displayRequestMask = 0x0;
141 std::vector<int64_t> requestedLayers;
142 std::vector<int32_t> requestMasks;
143 ClientTargetProperty clientTargetProperty{common::PixelFormat::RGBA_8888,
144 common::Dataspace::UNKNOWN};
145 DimmingStage dimmingStage;
146 auto err =
147 mHal->validateDisplay(display, &changedLayers, &compositionTypes, &displayRequestMask,
148 &requestedLayers, &requestMasks, &clientTargetProperty,
149 &dimmingStage);
150 mResources->setDisplayMustValidateState(display, false);
151 if (err == HWC2_ERROR_NONE || err == HWC2_ERROR_HAS_CHANGES) {
152 mWriter->setChangedCompositionTypes(display, changedLayers, compositionTypes);
153 mWriter->setDisplayRequests(display, displayRequestMask, requestedLayers, requestMasks);
154 static constexpr float kBrightness = 1.f;
155 mWriter->setClientTargetProperty(display, clientTargetProperty, kBrightness, dimmingStage);
156 } else {
157 LOG(ERROR) << __func__ << ": err " << err;
158 mWriter->setError(mCommandIndex, err);
159 }
160 return err;
161 }
162
executeSetColorTransform(int64_t display,const std::vector<float> & matrix)163 void ComposerCommandEngine::executeSetColorTransform(int64_t display,
164 const std::vector<float>& matrix) {
165 auto err = mHal->setColorTransform(display, matrix);
166 if (err) {
167 LOG(ERROR) << __func__ << ": err " << err;
168 mWriter->setError(mCommandIndex, err);
169 }
170 }
171
executeSetClientTarget(int64_t display,const ClientTarget & command)172 void ComposerCommandEngine::executeSetClientTarget(int64_t display, const ClientTarget& command) {
173 bool useCache = !command.buffer.handle;
174 buffer_handle_t handle = useCache
175 ? nullptr
176 : ::android::makeFromAidl(*command.buffer.handle);
177 buffer_handle_t clientTarget;
178 auto bufferReleaser = mResources->createReleaser(true);
179 auto err = mResources->getDisplayClientTarget(display, command.buffer.slot, useCache, handle,
180 clientTarget, bufferReleaser.get());
181 if (!err) {
182 err = mHal->setClientTarget(display, clientTarget, command.buffer.fence,
183 command.dataspace, command.damage);
184 if (err) {
185 LOG(ERROR) << __func__ << " setClientTarget: err " << err;
186 mWriter->setError(mCommandIndex, err);
187 }
188 } else {
189 LOG(ERROR) << __func__ << " getDisplayClientTarget : err " << err;
190 mWriter->setError(mCommandIndex, err);
191 }
192 }
193
executeSetOutputBuffer(uint64_t display,const Buffer & buffer)194 void ComposerCommandEngine::executeSetOutputBuffer(uint64_t display, const Buffer& buffer) {
195 bool useCache = !buffer.handle;
196 buffer_handle_t handle = useCache
197 ? nullptr
198 : ::android::makeFromAidl(*buffer.handle);
199 buffer_handle_t outputBuffer;
200 auto bufferReleaser = mResources->createReleaser(true);
201 auto err = mResources->getDisplayOutputBuffer(display, buffer.slot, useCache, handle,
202 outputBuffer, bufferReleaser.get());
203 if (!err) {
204 err = mHal->setOutputBuffer(display, outputBuffer, buffer.fence);
205 if (err) {
206 LOG(ERROR) << __func__ << " setOutputBuffer: err " << err;
207 mWriter->setError(mCommandIndex, err);
208 }
209 } else {
210 LOG(ERROR) << __func__ << " getDisplayOutputBuffer: err " << err;
211 mWriter->setError(mCommandIndex, err);
212 }
213 }
214
executeSetExpectedPresentTimeInternal(int64_t display,const std::optional<ClockMonotonicTimestamp> expectedPresentTime)215 void ComposerCommandEngine::executeSetExpectedPresentTimeInternal(
216 int64_t display, const std::optional<ClockMonotonicTimestamp> expectedPresentTime) {
217 mHal->setExpectedPresentTime(display, expectedPresentTime);
218 }
219
executeValidateDisplay(int64_t display,const std::optional<ClockMonotonicTimestamp> expectedPresentTime)220 void ComposerCommandEngine::executeValidateDisplay(
221 int64_t display, const std::optional<ClockMonotonicTimestamp> expectedPresentTime) {
222 executeSetExpectedPresentTimeInternal(display, expectedPresentTime);
223 executeValidateDisplayInternal(display);
224 }
225
executeSetDisplayBrightness(uint64_t display,const DisplayBrightness & command)226 void ComposerCommandEngine::executeSetDisplayBrightness(uint64_t display,
227 const DisplayBrightness& command) {
228 auto err = mHal->setDisplayBrightness(display, command.brightness);
229 if (err) {
230 LOG(ERROR) << __func__ << ": err " << err;
231 mWriter->setError(mCommandIndex, err);
232 }
233 }
234
executePresentOrValidateDisplay(int64_t display,const std::optional<ClockMonotonicTimestamp> expectedPresentTime)235 void ComposerCommandEngine::executePresentOrValidateDisplay(
236 int64_t display, const std::optional<ClockMonotonicTimestamp> expectedPresentTime) {
237 executeSetExpectedPresentTimeInternal(display, expectedPresentTime);
238 // First try to Present as is.
239 auto presentErr = mResources->mustValidateDisplay(display) ? IComposerClient::EX_NOT_VALIDATED
240 : executePresentDisplay(display);
241 if (!presentErr) {
242 mWriter->setPresentOrValidateResult(display, PresentOrValidate::Result::Presented);
243 return;
244 }
245
246 // Fallback to validate
247 auto validateErr = executeValidateDisplayInternal(display);
248 if (validateErr != HWC2_ERROR_NONE && validateErr != HWC2_ERROR_HAS_CHANGES) return;
249
250 bool hasClientComp = false;
251 bool cannotPresentDirectly = (validateErr == HWC2_ERROR_HAS_CHANGES) ||
252 (mHal->getHasClientComposition(display, hasClientComp) == HWC2_ERROR_NONE &&
253 hasClientComp);
254 if (cannotPresentDirectly) {
255 mWriter->setPresentOrValidateResult(display, PresentOrValidate::Result::Validated);
256 return;
257 }
258
259 // Try to call present again
260 executeAcceptDisplayChanges(display);
261 presentErr = executePresentDisplay(display);
262 if (!presentErr) {
263 mWriter->setPresentOrValidateResult(display, PresentOrValidate::Result::Presented);
264 }
265 }
266
executeAcceptDisplayChanges(int64_t display)267 void ComposerCommandEngine::executeAcceptDisplayChanges(int64_t display) {
268 auto err = mHal->acceptDisplayChanges(display);
269 if (err) {
270 LOG(ERROR) << __func__ << ": err " << err;
271 mWriter->setError(mCommandIndex, err);
272 }
273 }
274
executePresentDisplay(int64_t display)275 int ComposerCommandEngine::executePresentDisplay(int64_t display) {
276 ndk::ScopedFileDescriptor presentFence;
277 std::vector<int64_t> layers;
278 std::vector<ndk::ScopedFileDescriptor> fences;
279 auto err = mHal->presentDisplay(display, presentFence, &layers, &fences);
280 if (!err) {
281 mWriter->setPresentFence(display, std::move(presentFence));
282 mWriter->setReleaseFences(display, layers, std::move(fences));
283 }
284
285 return err;
286 }
287
executeSetLayerCursorPosition(int64_t display,int64_t layer,const common::Point & cursorPosition)288 void ComposerCommandEngine::executeSetLayerCursorPosition(int64_t display, int64_t layer,
289 const common::Point& cursorPosition) {
290 auto err = mHal->setLayerCursorPosition(display, layer, cursorPosition.x, cursorPosition.y);
291 if (err) {
292 LOG(ERROR) << __func__ << ": err " << err;
293 mWriter->setError(mCommandIndex, err);
294 }
295 }
296
executeSetLayerBuffer(int64_t display,int64_t layer,const Buffer & buffer)297 void ComposerCommandEngine::executeSetLayerBuffer(int64_t display, int64_t layer,
298 const Buffer& buffer) {
299 bool useCache = !buffer.handle;
300 buffer_handle_t handle = useCache
301 ? nullptr
302 : ::android::makeFromAidl(*buffer.handle);
303 buffer_handle_t hwcBuffer;
304 auto bufferReleaser = mResources->createReleaser(true);
305 auto err = mResources->getLayerBuffer(display, layer, buffer.slot, useCache,
306 handle, hwcBuffer, bufferReleaser.get());
307 if (!err) {
308 err = mHal->setLayerBuffer(display, layer, hwcBuffer, buffer.fence);
309 if (err) {
310 LOG(ERROR) << __func__ << ": setLayerBuffer err " << err;
311 mWriter->setError(mCommandIndex, err);
312 }
313 } else {
314 LOG(ERROR) << __func__ << ": getLayerBuffer err " << err;
315 mWriter->setError(mCommandIndex, err);
316 }
317 }
318
executeSetLayerSurfaceDamage(int64_t display,int64_t layer,const std::vector<std::optional<common::Rect>> & damage)319 void ComposerCommandEngine::executeSetLayerSurfaceDamage(int64_t display, int64_t layer,
320 const std::vector<std::optional<common::Rect>>& damage) {
321 auto err = mHal->setLayerSurfaceDamage(display, layer, damage);
322 if (err) {
323 LOG(ERROR) << __func__ << ": err " << err;
324 mWriter->setError(mCommandIndex, err);
325 }
326 }
327
executeSetLayerBlendMode(int64_t display,int64_t layer,const ParcelableBlendMode & blendMode)328 void ComposerCommandEngine::executeSetLayerBlendMode(int64_t display, int64_t layer,
329 const ParcelableBlendMode& blendMode) {
330 auto err = mHal->setLayerBlendMode(display, layer, blendMode.blendMode);
331 if (err) {
332 LOG(ERROR) << __func__ << ": err " << err;
333 mWriter->setError(mCommandIndex, err);
334 }
335 }
336
executeSetLayerColor(int64_t display,int64_t layer,const Color & color)337 void ComposerCommandEngine::executeSetLayerColor(int64_t display, int64_t layer,
338 const Color& color) {
339 auto err = mHal->setLayerColor(display, layer, color);
340 if (err) {
341 LOG(ERROR) << __func__ << ": err " << err;
342 mWriter->setError(mCommandIndex, err);
343 }
344 }
345
executeSetLayerComposition(int64_t display,int64_t layer,const ParcelableComposition & composition)346 void ComposerCommandEngine::executeSetLayerComposition(int64_t display, int64_t layer,
347 const ParcelableComposition& composition) {
348 auto err = mHal->setLayerCompositionType(display, layer, composition.composition);
349 if (err) {
350 LOG(ERROR) << __func__ << ": err " << err;
351 mWriter->setError(mCommandIndex, err);
352 }
353 }
354
executeSetLayerDataspace(int64_t display,int64_t layer,const ParcelableDataspace & dataspace)355 void ComposerCommandEngine::executeSetLayerDataspace(int64_t display, int64_t layer,
356 const ParcelableDataspace& dataspace) {
357 auto err = mHal->setLayerDataspace(display, layer, dataspace.dataspace);
358 if (err) {
359 LOG(ERROR) << __func__ << ": err " << err;
360 mWriter->setError(mCommandIndex, err);
361 }
362 }
363
executeSetLayerDisplayFrame(int64_t display,int64_t layer,const common::Rect & rect)364 void ComposerCommandEngine::executeSetLayerDisplayFrame(int64_t display, int64_t layer,
365 const common::Rect& rect) {
366 auto err = mHal->setLayerDisplayFrame(display, layer, rect);
367 if (err) {
368 LOG(ERROR) << __func__ << ": err " << err;
369 mWriter->setError(mCommandIndex, err);
370 }
371 }
372
executeSetLayerPlaneAlpha(int64_t display,int64_t layer,const PlaneAlpha & planeAlpha)373 void ComposerCommandEngine::executeSetLayerPlaneAlpha(int64_t display, int64_t layer,
374 const PlaneAlpha& planeAlpha) {
375 auto err = mHal->setLayerPlaneAlpha(display, layer, planeAlpha.alpha);
376 if (err) {
377 LOG(ERROR) << __func__ << ": err " << err;
378 mWriter->setError(mCommandIndex, err);
379 }
380 }
381
executeSetLayerSidebandStream(int64_t display,int64_t layer,const AidlNativeHandle & sidebandStream)382 void ComposerCommandEngine::executeSetLayerSidebandStream(int64_t display, int64_t layer,
383 const AidlNativeHandle& sidebandStream) {
384 buffer_handle_t handle = ::android::makeFromAidl(sidebandStream);
385 buffer_handle_t stream;
386
387 auto bufferReleaser = mResources->createReleaser(false);
388 auto err = mResources->getLayerSidebandStream(display, layer, handle,
389 stream, bufferReleaser.get());
390 if (err) {
391 err = mHal->setLayerSidebandStream(display, layer, stream);
392 }
393 if (err) {
394 LOG(ERROR) << __func__ << ": err " << err;
395 mWriter->setError(mCommandIndex, err);
396 }
397 }
398
executeSetLayerSourceCrop(int64_t display,int64_t layer,const common::FRect & sourceCrop)399 void ComposerCommandEngine::executeSetLayerSourceCrop(int64_t display, int64_t layer,
400 const common::FRect& sourceCrop) {
401 auto err = mHal->setLayerSourceCrop(display, layer, sourceCrop);
402 if (err) {
403 LOG(ERROR) << __func__ << ": err " << err;
404 mWriter->setError(mCommandIndex, err);
405 }
406 }
407
executeSetLayerTransform(int64_t display,int64_t layer,const ParcelableTransform & transform)408 void ComposerCommandEngine::executeSetLayerTransform(int64_t display, int64_t layer,
409 const ParcelableTransform& transform) {
410 auto err = mHal->setLayerTransform(display, layer, transform.transform);
411 if (err) {
412 LOG(ERROR) << __func__ << ": err " << err;
413 mWriter->setError(mCommandIndex, err);
414 }
415 }
416
executeSetLayerVisibleRegion(int64_t display,int64_t layer,const std::vector<std::optional<common::Rect>> & visibleRegion)417 void ComposerCommandEngine::executeSetLayerVisibleRegion(int64_t display, int64_t layer,
418 const std::vector<std::optional<common::Rect>>& visibleRegion) {
419 auto err = mHal->setLayerVisibleRegion(display, layer, visibleRegion);
420 if (err) {
421 LOG(ERROR) << __func__ << ": err " << err;
422 mWriter->setError(mCommandIndex, err);
423 }
424 }
425
executeSetLayerZOrder(int64_t display,int64_t layer,const ZOrder & zOrder)426 void ComposerCommandEngine::executeSetLayerZOrder(int64_t display, int64_t layer,
427 const ZOrder& zOrder) {
428 auto err = mHal->setLayerZOrder(display, layer, zOrder.z);
429 if (err) {
430 LOG(ERROR) << __func__ << ": err " << err;
431 mWriter->setError(mCommandIndex, err);
432 }
433 }
434
executeSetLayerPerFrameMetadata(int64_t display,int64_t layer,const std::vector<std::optional<PerFrameMetadata>> & perFrameMetadata)435 void ComposerCommandEngine::executeSetLayerPerFrameMetadata(int64_t display, int64_t layer,
436 const std::vector<std::optional<PerFrameMetadata>>& perFrameMetadata) {
437 auto err = mHal->setLayerPerFrameMetadata(display, layer, perFrameMetadata);
438 if (err) {
439 LOG(ERROR) << __func__ << ": err " << err;
440 mWriter->setError(mCommandIndex, err);
441 }
442 }
443
executeSetLayerColorTransform(int64_t display,int64_t layer,const std::vector<float> & matrix)444 void ComposerCommandEngine::executeSetLayerColorTransform(int64_t display, int64_t layer,
445 const std::vector<float>& matrix) {
446 auto err = mHal->setLayerColorTransform(display, layer, matrix);
447 if (err) {
448 LOG(ERROR) << __func__ << ": err " << err;
449 mWriter->setError(mCommandIndex, err);
450 }
451 }
452
executeSetLayerBrightness(int64_t display,int64_t layer,const LayerBrightness & brightness)453 void ComposerCommandEngine::executeSetLayerBrightness(int64_t display, int64_t layer,
454 const LayerBrightness& brightness) {
455 auto err = mHal->setLayerBrightness(display, layer, brightness.brightness);
456 if (err) {
457 LOG(ERROR) << __func__ << ": err " << err;
458 mWriter->setError(mCommandIndex, err);
459 }
460 }
461
executeSetLayerPerFrameMetadataBlobs(int64_t display,int64_t layer,const std::vector<std::optional<PerFrameMetadataBlob>> & metadata)462 void ComposerCommandEngine::executeSetLayerPerFrameMetadataBlobs(int64_t display, int64_t layer,
463 const std::vector<std::optional<PerFrameMetadataBlob>>& metadata) {
464 auto err = mHal->setLayerPerFrameMetadataBlobs(display, layer, metadata);
465 if (err) {
466 LOG(ERROR) << __func__ << ": err " << err;
467 mWriter->setError(mCommandIndex, err);
468 }
469 }
470
471 } // namespace aidl::android::hardware::graphics::composer3::impl
472