1 /*
2  * Copyright 2018 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 #pragma once
18 
19 #ifndef LOG_TAG
20 #warning "ComposerCommandEngine.h included without LOG_TAG"
21 #endif
22 
23 #include <vector>
24 
25 #include <composer-command-buffer/2.1/ComposerCommandBuffer.h>
26 #include <composer-hal/2.1/ComposerHal.h>
27 #include <composer-hal/2.1/ComposerResources.h>
28 // TODO remove hwcomposer_defs.h dependency
29 #include <hardware/hwcomposer_defs.h>
30 #include <log/log.h>
31 
32 namespace android {
33 namespace hardware {
34 namespace graphics {
35 namespace composer {
36 namespace V2_1 {
37 namespace hal {
38 
39 // TODO own a CommandReaderBase rather than subclassing
40 class ComposerCommandEngine : protected CommandReaderBase {
41    public:
ComposerCommandEngine(ComposerHal * hal,ComposerResources * resources)42     ComposerCommandEngine(ComposerHal* hal, ComposerResources* resources)
43         : mHal(hal), mResources(resources) {}
44 
45     virtual ~ComposerCommandEngine() = default;
46 
setInputMQDescriptor(const MQDescriptorSync<uint32_t> & descriptor)47     bool setInputMQDescriptor(const MQDescriptorSync<uint32_t>& descriptor) {
48         return setMQDescriptor(descriptor);
49     }
50 
execute(uint32_t inLength,const hidl_vec<hidl_handle> & inHandles,bool * outQueueChanged,uint32_t * outCommandLength,hidl_vec<hidl_handle> * outCommandHandles)51     Error execute(uint32_t inLength, const hidl_vec<hidl_handle>& inHandles, bool* outQueueChanged,
52                   uint32_t* outCommandLength, hidl_vec<hidl_handle>* outCommandHandles) {
53         if (!readQueue(inLength, inHandles)) {
54             return Error::BAD_PARAMETER;
55         }
56 
57         IComposerClient::Command command;
58         uint16_t length = 0;
59         while (!isEmpty()) {
60             if (!beginCommand(&command, &length)) {
61                 break;
62             }
63 
64             bool parsed = executeCommand(command, length);
65             endCommand();
66 
67             if (!parsed) {
68                 ALOGE("failed to parse command 0x%x, length %" PRIu16, command, length);
69                 break;
70             }
71         }
72 
73         if (!isEmpty()) {
74             return Error::BAD_PARAMETER;
75         }
76 
77         return mWriter.writeQueue(outQueueChanged, outCommandLength, outCommandHandles)
78                    ? Error::NONE
79                    : Error::NO_RESOURCES;
80     }
81 
getOutputMQDescriptor()82     const MQDescriptorSync<uint32_t>* getOutputMQDescriptor() { return mWriter.getMQDescriptor(); }
83 
reset()84     void reset() {
85         CommandReaderBase::reset();
86         mWriter.reset();
87     }
88 
89    protected:
executeCommand(IComposerClient::Command command,uint16_t length)90     virtual bool executeCommand(IComposerClient::Command command, uint16_t length) {
91         switch (command) {
92             case IComposerClient::Command::SELECT_DISPLAY:
93                 return executeSelectDisplay(length);
94             case IComposerClient::Command::SELECT_LAYER:
95                 return executeSelectLayer(length);
96             case IComposerClient::Command::SET_COLOR_TRANSFORM:
97                 return executeSetColorTransform(length);
98             case IComposerClient::Command::SET_CLIENT_TARGET:
99                 return executeSetClientTarget(length);
100             case IComposerClient::Command::SET_OUTPUT_BUFFER:
101                 return executeSetOutputBuffer(length);
102             case IComposerClient::Command::VALIDATE_DISPLAY:
103                 return executeValidateDisplay(length);
104             case IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY:
105                 return executePresentOrValidateDisplay(length);
106             case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
107                 return executeAcceptDisplayChanges(length);
108             case IComposerClient::Command::PRESENT_DISPLAY:
109                 return executePresentDisplay(length);
110             case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
111                 return executeSetLayerCursorPosition(length);
112             case IComposerClient::Command::SET_LAYER_BUFFER:
113                 return executeSetLayerBuffer(length);
114             case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
115                 return executeSetLayerSurfaceDamage(length);
116             case IComposerClient::Command::SET_LAYER_BLEND_MODE:
117                 return executeSetLayerBlendMode(length);
118             case IComposerClient::Command::SET_LAYER_COLOR:
119                 return executeSetLayerColor(length);
120             case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
121                 return executeSetLayerCompositionType(length);
122             case IComposerClient::Command::SET_LAYER_DATASPACE:
123                 return executeSetLayerDataspace(length);
124             case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
125                 return executeSetLayerDisplayFrame(length);
126             case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
127                 return executeSetLayerPlaneAlpha(length);
128             case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
129                 return executeSetLayerSidebandStream(length);
130             case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
131                 return executeSetLayerSourceCrop(length);
132             case IComposerClient::Command::SET_LAYER_TRANSFORM:
133                 return executeSetLayerTransform(length);
134             case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
135                 return executeSetLayerVisibleRegion(length);
136             case IComposerClient::Command::SET_LAYER_Z_ORDER:
137                 return executeSetLayerZOrder(length);
138             default:
139                 return false;
140         }
141     }
142 
executeSelectDisplay(uint16_t length)143     bool executeSelectDisplay(uint16_t length) {
144         if (length != CommandWriterBase::kSelectDisplayLength) {
145             return false;
146         }
147 
148         mCurrentDisplay = read64();
149         mWriter.selectDisplay(mCurrentDisplay);
150 
151         return true;
152     }
153 
executeSelectLayer(uint16_t length)154     bool executeSelectLayer(uint16_t length) {
155         if (length != CommandWriterBase::kSelectLayerLength) {
156             return false;
157         }
158 
159         mCurrentLayer = read64();
160 
161         return true;
162     }
163 
executeSetColorTransform(uint16_t length)164     bool executeSetColorTransform(uint16_t length) {
165         if (length != CommandWriterBase::kSetColorTransformLength) {
166             return false;
167         }
168 
169         float matrix[16];
170         for (int i = 0; i < 16; i++) {
171             matrix[i] = readFloat();
172         }
173         auto transform = readSigned();
174 
175         auto err = mHal->setColorTransform(mCurrentDisplay, matrix, transform);
176         if (err != Error::NONE) {
177             mWriter.setError(getCommandLoc(), err);
178         }
179 
180         return true;
181     }
182 
executeSetClientTarget(uint16_t length)183     bool executeSetClientTarget(uint16_t length) {
184         // 4 parameters followed by N rectangles
185         if ((length - 4) % 4 != 0) {
186             return false;
187         }
188 
189         bool useCache = false;
190         auto slot = read();
191         auto rawHandle = readHandle(&useCache);
192         auto fence = readFence();
193         auto dataspace = readSigned();
194         auto damage = readRegion((length - 4) / 4);
195         bool closeFence = true;
196 
197         const native_handle_t* clientTarget;
198         ComposerResources::ReplacedBufferHandle replacedClientTarget;
199         auto err = mResources->getDisplayClientTarget(mCurrentDisplay, slot, useCache, rawHandle,
200                                                       &clientTarget, &replacedClientTarget);
201         if (err == Error::NONE) {
202             err = mHal->setClientTarget(mCurrentDisplay, clientTarget, fence, dataspace, damage);
203             if (err == Error::NONE) {
204                 closeFence = false;
205             }
206         }
207         if (closeFence) {
208             close(fence);
209         }
210         if (err != Error::NONE) {
211             mWriter.setError(getCommandLoc(), err);
212         }
213 
214         return true;
215     }
216 
executeSetOutputBuffer(uint16_t length)217     bool executeSetOutputBuffer(uint16_t length) {
218         if (length != CommandWriterBase::kSetOutputBufferLength) {
219             return false;
220         }
221 
222         bool useCache = false;
223         auto slot = read();
224         auto rawhandle = readHandle(&useCache);
225         auto fence = readFence();
226         bool closeFence = true;
227 
228         const native_handle_t* outputBuffer;
229         ComposerResources::ReplacedBufferHandle replacedOutputBuffer;
230         auto err = mResources->getDisplayOutputBuffer(mCurrentDisplay, slot, useCache, rawhandle,
231                                                       &outputBuffer, &replacedOutputBuffer);
232         if (err == Error::NONE) {
233             err = mHal->setOutputBuffer(mCurrentDisplay, outputBuffer, fence);
234             if (err == Error::NONE) {
235                 closeFence = false;
236             }
237         }
238         if (closeFence) {
239             close(fence);
240         }
241         if (err != Error::NONE) {
242             mWriter.setError(getCommandLoc(), err);
243         }
244 
245         return true;
246     }
247 
executeValidateDisplay(uint16_t length)248     bool executeValidateDisplay(uint16_t length) {
249         if (length != CommandWriterBase::kValidateDisplayLength) {
250             return false;
251         }
252 
253         std::vector<Layer> changedLayers;
254         std::vector<IComposerClient::Composition> compositionTypes;
255         uint32_t displayRequestMask = 0x0;
256         std::vector<Layer> requestedLayers;
257         std::vector<uint32_t> requestMasks;
258 
259         auto err = mHal->validateDisplay(mCurrentDisplay, &changedLayers, &compositionTypes,
260                                          &displayRequestMask, &requestedLayers, &requestMasks);
261         mResources->setDisplayMustValidateState(mCurrentDisplay, false);
262         if (err == Error::NONE) {
263             mWriter.setChangedCompositionTypes(changedLayers, compositionTypes);
264             mWriter.setDisplayRequests(displayRequestMask, requestedLayers, requestMasks);
265         } else {
266             mWriter.setError(getCommandLoc(), err);
267         }
268 
269         return true;
270     }
271 
executePresentOrValidateDisplay(uint16_t length)272     bool executePresentOrValidateDisplay(uint16_t length) {
273         if (length != CommandWriterBase::kPresentOrValidateDisplayLength) {
274             return false;
275         }
276 
277         // First try to Present as is.
278         if (mHal->hasCapability(HWC2_CAPABILITY_SKIP_VALIDATE)) {
279             int presentFence = -1;
280             std::vector<Layer> layers;
281             std::vector<int> fences;
282             auto err = mResources->mustValidateDisplay(mCurrentDisplay)
283                            ? Error::NOT_VALIDATED
284                            : mHal->presentDisplay(mCurrentDisplay, &presentFence, &layers, &fences);
285             if (err == Error::NONE) {
286                 mWriter.setPresentOrValidateResult(1);
287                 mWriter.setPresentFence(presentFence);
288                 mWriter.setReleaseFences(layers, fences);
289                 return true;
290             }
291         }
292 
293         // Present has failed. We need to fallback to validate
294         std::vector<Layer> changedLayers;
295         std::vector<IComposerClient::Composition> compositionTypes;
296         uint32_t displayRequestMask = 0x0;
297         std::vector<Layer> requestedLayers;
298         std::vector<uint32_t> requestMasks;
299 
300         auto err = mHal->validateDisplay(mCurrentDisplay, &changedLayers, &compositionTypes,
301                                          &displayRequestMask, &requestedLayers, &requestMasks);
302         mResources->setDisplayMustValidateState(mCurrentDisplay, false);
303         if (err == Error::NONE) {
304             mWriter.setPresentOrValidateResult(0);
305             mWriter.setChangedCompositionTypes(changedLayers, compositionTypes);
306             mWriter.setDisplayRequests(displayRequestMask, requestedLayers, requestMasks);
307         } else {
308             mWriter.setError(getCommandLoc(), err);
309         }
310 
311         return true;
312     }
313 
executeAcceptDisplayChanges(uint16_t length)314     bool executeAcceptDisplayChanges(uint16_t length) {
315         if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
316             return false;
317         }
318 
319         auto err = mHal->acceptDisplayChanges(mCurrentDisplay);
320         if (err != Error::NONE) {
321             mWriter.setError(getCommandLoc(), err);
322         }
323 
324         return true;
325     }
326 
executePresentDisplay(uint16_t length)327     bool executePresentDisplay(uint16_t length) {
328         if (length != CommandWriterBase::kPresentDisplayLength) {
329             return false;
330         }
331 
332         int presentFence = -1;
333         std::vector<Layer> layers;
334         std::vector<int> fences;
335         auto err = mHal->presentDisplay(mCurrentDisplay, &presentFence, &layers, &fences);
336         if (err == Error::NONE) {
337             mWriter.setPresentFence(presentFence);
338             mWriter.setReleaseFences(layers, fences);
339         } else {
340             mWriter.setError(getCommandLoc(), err);
341         }
342 
343         return true;
344     }
345 
executeSetLayerCursorPosition(uint16_t length)346     bool executeSetLayerCursorPosition(uint16_t length) {
347         if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
348             return false;
349         }
350 
351         auto err = mHal->setLayerCursorPosition(mCurrentDisplay, mCurrentLayer, readSigned(),
352                                                 readSigned());
353         if (err != Error::NONE) {
354             mWriter.setError(getCommandLoc(), err);
355         }
356 
357         return true;
358     }
359 
executeSetLayerBuffer(uint16_t length)360     bool executeSetLayerBuffer(uint16_t length) {
361         if (length != CommandWriterBase::kSetLayerBufferLength) {
362             return false;
363         }
364 
365         bool useCache = false;
366         auto slot = read();
367         auto rawHandle = readHandle(&useCache);
368         auto fence = readFence();
369         bool closeFence = true;
370 
371         const native_handle_t* buffer;
372         ComposerResources::ReplacedBufferHandle replacedBuffer;
373         auto err = mResources->getLayerBuffer(mCurrentDisplay, mCurrentLayer, slot, useCache,
374                                               rawHandle, &buffer, &replacedBuffer);
375         if (err == Error::NONE) {
376             err = mHal->setLayerBuffer(mCurrentDisplay, mCurrentLayer, buffer, fence);
377             if (err == Error::NONE) {
378                 closeFence = false;
379             }
380         }
381         if (closeFence) {
382             close(fence);
383         }
384         if (err != Error::NONE) {
385             mWriter.setError(getCommandLoc(), err);
386         }
387 
388         return true;
389     }
390 
executeSetLayerSurfaceDamage(uint16_t length)391     bool executeSetLayerSurfaceDamage(uint16_t length) {
392         // N rectangles
393         if (length % 4 != 0) {
394             return false;
395         }
396 
397         auto damage = readRegion(length / 4);
398         auto err = mHal->setLayerSurfaceDamage(mCurrentDisplay, mCurrentLayer, damage);
399         if (err != Error::NONE) {
400             mWriter.setError(getCommandLoc(), err);
401         }
402 
403         return true;
404     }
405 
executeSetLayerBlendMode(uint16_t length)406     bool executeSetLayerBlendMode(uint16_t length) {
407         if (length != CommandWriterBase::kSetLayerBlendModeLength) {
408             return false;
409         }
410 
411         auto err = mHal->setLayerBlendMode(mCurrentDisplay, mCurrentLayer, readSigned());
412         if (err != Error::NONE) {
413             mWriter.setError(getCommandLoc(), err);
414         }
415 
416         return true;
417     }
418 
executeSetLayerColor(uint16_t length)419     bool executeSetLayerColor(uint16_t length) {
420         if (length != CommandWriterBase::kSetLayerColorLength) {
421             return false;
422         }
423 
424         auto err = mHal->setLayerColor(mCurrentDisplay, mCurrentLayer, readColor());
425         if (err != Error::NONE) {
426             mWriter.setError(getCommandLoc(), err);
427         }
428 
429         return true;
430     }
431 
executeSetLayerCompositionType(uint16_t length)432     bool executeSetLayerCompositionType(uint16_t length) {
433         if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
434             return false;
435         }
436 
437         auto err = mHal->setLayerCompositionType(mCurrentDisplay, mCurrentLayer, readSigned());
438         if (err != Error::NONE) {
439             mWriter.setError(getCommandLoc(), err);
440         }
441 
442         return true;
443     }
444 
executeSetLayerDataspace(uint16_t length)445     bool executeSetLayerDataspace(uint16_t length) {
446         if (length != CommandWriterBase::kSetLayerDataspaceLength) {
447             return false;
448         }
449 
450         auto err = mHal->setLayerDataspace(mCurrentDisplay, mCurrentLayer, readSigned());
451         if (err != Error::NONE) {
452             mWriter.setError(getCommandLoc(), err);
453         }
454 
455         return true;
456     }
457 
executeSetLayerDisplayFrame(uint16_t length)458     bool executeSetLayerDisplayFrame(uint16_t length) {
459         if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
460             return false;
461         }
462 
463         auto err = mHal->setLayerDisplayFrame(mCurrentDisplay, mCurrentLayer, readRect());
464         if (err != Error::NONE) {
465             mWriter.setError(getCommandLoc(), err);
466         }
467 
468         return true;
469     }
470 
executeSetLayerPlaneAlpha(uint16_t length)471     bool executeSetLayerPlaneAlpha(uint16_t length) {
472         if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
473             return false;
474         }
475 
476         auto err = mHal->setLayerPlaneAlpha(mCurrentDisplay, mCurrentLayer, readFloat());
477         if (err != Error::NONE) {
478             mWriter.setError(getCommandLoc(), err);
479         }
480 
481         return true;
482     }
483 
executeSetLayerSidebandStream(uint16_t length)484     bool executeSetLayerSidebandStream(uint16_t length) {
485         if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
486             return false;
487         }
488 
489         auto rawHandle = readHandle();
490 
491         const native_handle_t* stream;
492         ComposerResources::ReplacedStreamHandle replacedStream;
493         auto err = mResources->getLayerSidebandStream(mCurrentDisplay, mCurrentLayer, rawHandle,
494                                                       &stream, &replacedStream);
495         if (err == Error::NONE) {
496             err = mHal->setLayerSidebandStream(mCurrentDisplay, mCurrentLayer, stream);
497         }
498         if (err != Error::NONE) {
499             mWriter.setError(getCommandLoc(), err);
500         }
501 
502         return true;
503     }
504 
executeSetLayerSourceCrop(uint16_t length)505     bool executeSetLayerSourceCrop(uint16_t length) {
506         if (length != CommandWriterBase::kSetLayerSourceCropLength) {
507             return false;
508         }
509 
510         auto err = mHal->setLayerSourceCrop(mCurrentDisplay, mCurrentLayer, readFRect());
511         if (err != Error::NONE) {
512             mWriter.setError(getCommandLoc(), err);
513         }
514 
515         return true;
516     }
517 
executeSetLayerTransform(uint16_t length)518     bool executeSetLayerTransform(uint16_t length) {
519         if (length != CommandWriterBase::kSetLayerTransformLength) {
520             return false;
521         }
522 
523         auto err = mHal->setLayerTransform(mCurrentDisplay, mCurrentLayer, readSigned());
524         if (err != Error::NONE) {
525             mWriter.setError(getCommandLoc(), err);
526         }
527 
528         return true;
529     }
530 
executeSetLayerVisibleRegion(uint16_t length)531     bool executeSetLayerVisibleRegion(uint16_t length) {
532         // N rectangles
533         if (length % 4 != 0) {
534             return false;
535         }
536 
537         auto region = readRegion(length / 4);
538         auto err = mHal->setLayerVisibleRegion(mCurrentDisplay, mCurrentLayer, region);
539         if (err != Error::NONE) {
540             mWriter.setError(getCommandLoc(), err);
541         }
542 
543         return true;
544     }
545 
executeSetLayerZOrder(uint16_t length)546     bool executeSetLayerZOrder(uint16_t length) {
547         if (length != CommandWriterBase::kSetLayerZOrderLength) {
548             return false;
549         }
550 
551         auto err = mHal->setLayerZOrder(mCurrentDisplay, mCurrentLayer, read());
552         if (err != Error::NONE) {
553             mWriter.setError(getCommandLoc(), err);
554         }
555 
556         return true;
557     }
558 
readRect()559     hwc_rect_t readRect() {
560         return hwc_rect_t{
561             readSigned(), readSigned(), readSigned(), readSigned(),
562         };
563     }
564 
readRegion(size_t count)565     std::vector<hwc_rect_t> readRegion(size_t count) {
566         std::vector<hwc_rect_t> region;
567         region.reserve(count);
568         while (count > 0) {
569             region.emplace_back(readRect());
570             count--;
571         }
572 
573         return region;
574     }
575 
readFRect()576     hwc_frect_t readFRect() {
577         return hwc_frect_t{
578             readFloat(), readFloat(), readFloat(), readFloat(),
579         };
580     }
581 
582     ComposerHal* mHal;
583     ComposerResources* mResources;
584 
585     // 64KiB minus a small space for metadata such as read/write pointers
586     static constexpr size_t kWriterInitialSize = 64 * 1024 / sizeof(uint32_t) - 16;
587     CommandWriterBase mWriter{kWriterInitialSize};
588 
589     Display mCurrentDisplay = 0;
590     Layer mCurrentLayer = 0;
591 };
592 
593 }  // namespace hal
594 }  // namespace V2_1
595 }  // namespace composer
596 }  // namespace graphics
597 }  // namespace hardware
598 }  // namespace android
599