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