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