1 /*
2  * Copyright 2019 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 <SurfaceFlingerProperties.sysprop.h>
18 #include <android-base/stringprintf.h>
19 #include <compositionengine/CompositionEngine.h>
20 #include <compositionengine/CompositionRefreshArgs.h>
21 #include <compositionengine/DisplayColorProfile.h>
22 #include <compositionengine/LayerFE.h>
23 #include <compositionengine/LayerFECompositionState.h>
24 #include <compositionengine/RenderSurface.h>
25 #include <compositionengine/impl/Output.h>
26 #include <compositionengine/impl/OutputCompositionState.h>
27 #include <compositionengine/impl/OutputLayer.h>
28 #include <compositionengine/impl/OutputLayerCompositionState.h>
29 #include <compositionengine/impl/planner/Planner.h>
30 
31 #include <thread>
32 
33 #include "renderengine/ExternalTexture.h"
34 
35 // TODO(b/129481165): remove the #pragma below and fix conversion issues
36 #pragma clang diagnostic push
37 #pragma clang diagnostic ignored "-Wconversion"
38 
39 #include <renderengine/DisplaySettings.h>
40 #include <renderengine/RenderEngine.h>
41 
42 // TODO(b/129481165): remove the #pragma below and fix conversion issues
43 #pragma clang diagnostic pop // ignored "-Wconversion"
44 
45 #include <android-base/properties.h>
46 #include <ui/DebugUtils.h>
47 #include <ui/HdrCapabilities.h>
48 #include <utils/Trace.h>
49 
50 #include "TracedOrdinal.h"
51 
52 namespace android::compositionengine {
53 
54 Output::~Output() = default;
55 
56 namespace impl {
57 
58 namespace {
59 
60 template <typename T>
61 class Reversed {
62 public:
Reversed(const T & container)63     explicit Reversed(const T& container) : mContainer(container) {}
begin()64     auto begin() { return mContainer.rbegin(); }
end()65     auto end() { return mContainer.rend(); }
66 
67 private:
68     const T& mContainer;
69 };
70 
71 // Helper for enumerating over a container in reverse order
72 template <typename T>
reversed(const T & c)73 Reversed<T> reversed(const T& c) {
74     return Reversed<T>(c);
75 }
76 
77 struct ScaleVector {
78     float x;
79     float y;
80 };
81 
82 // Returns a ScaleVector (x, y) such that from.scale(x, y) = to',
83 // where to' will have the same size as "to". In the case where "from" and "to"
84 // start at the origin to'=to.
getScale(const Rect & from,const Rect & to)85 ScaleVector getScale(const Rect& from, const Rect& to) {
86     return {.x = static_cast<float>(to.width()) / from.width(),
87             .y = static_cast<float>(to.height()) / from.height()};
88 }
89 
90 } // namespace
91 
createOutput(const compositionengine::CompositionEngine & compositionEngine)92 std::shared_ptr<Output> createOutput(
93         const compositionengine::CompositionEngine& compositionEngine) {
94     return createOutputTemplated<Output>(compositionEngine);
95 }
96 
97 Output::~Output() = default;
98 
isValid() const99 bool Output::isValid() const {
100     return mDisplayColorProfile && mDisplayColorProfile->isValid() && mRenderSurface &&
101             mRenderSurface->isValid();
102 }
103 
getDisplayId() const104 std::optional<DisplayId> Output::getDisplayId() const {
105     return {};
106 }
107 
getName() const108 const std::string& Output::getName() const {
109     return mName;
110 }
111 
setName(const std::string & name)112 void Output::setName(const std::string& name) {
113     mName = name;
114 }
115 
setCompositionEnabled(bool enabled)116 void Output::setCompositionEnabled(bool enabled) {
117     auto& outputState = editState();
118     if (outputState.isEnabled == enabled) {
119         return;
120     }
121 
122     outputState.isEnabled = enabled;
123     dirtyEntireOutput();
124 }
125 
setLayerCachingEnabled(bool enabled)126 void Output::setLayerCachingEnabled(bool enabled) {
127     if (enabled == (mPlanner != nullptr)) {
128         return;
129     }
130 
131     if (enabled) {
132         mPlanner = std::make_unique<planner::Planner>(getCompositionEngine().getRenderEngine());
133         if (mRenderSurface) {
134             mPlanner->setDisplaySize(mRenderSurface->getSize());
135         }
136     } else {
137         mPlanner.reset();
138     }
139 
140     for (auto* outputLayer : getOutputLayersOrderedByZ()) {
141         if (!outputLayer) {
142             continue;
143         }
144 
145         outputLayer->editState().overrideInfo = {};
146     }
147 }
148 
setLayerCachingTexturePoolEnabled(bool enabled)149 void Output::setLayerCachingTexturePoolEnabled(bool enabled) {
150     if (mPlanner) {
151         mPlanner->setTexturePoolEnabled(enabled);
152     }
153 }
154 
setProjection(ui::Rotation orientation,const Rect & layerStackSpaceRect,const Rect & orientedDisplaySpaceRect)155 void Output::setProjection(ui::Rotation orientation, const Rect& layerStackSpaceRect,
156                            const Rect& orientedDisplaySpaceRect) {
157     auto& outputState = editState();
158 
159     outputState.displaySpace.orientation = orientation;
160     LOG_FATAL_IF(outputState.displaySpace.bounds == Rect::INVALID_RECT,
161                  "The display bounds are unknown.");
162 
163     // Compute orientedDisplaySpace
164     ui::Size orientedSize = outputState.displaySpace.bounds.getSize();
165     if (orientation == ui::ROTATION_90 || orientation == ui::ROTATION_270) {
166         std::swap(orientedSize.width, orientedSize.height);
167     }
168     outputState.orientedDisplaySpace.bounds = Rect(orientedSize);
169     outputState.orientedDisplaySpace.content = orientedDisplaySpaceRect;
170 
171     // Compute displaySpace.content
172     const uint32_t transformOrientationFlags = ui::Transform::toRotationFlags(orientation);
173     ui::Transform rotation;
174     if (transformOrientationFlags != ui::Transform::ROT_INVALID) {
175         const auto displaySize = outputState.displaySpace.bounds;
176         rotation.set(transformOrientationFlags, displaySize.width(), displaySize.height());
177     }
178     outputState.displaySpace.content = rotation.transform(orientedDisplaySpaceRect);
179 
180     // Compute framebufferSpace
181     outputState.framebufferSpace.orientation = orientation;
182     LOG_FATAL_IF(outputState.framebufferSpace.bounds == Rect::INVALID_RECT,
183                  "The framebuffer bounds are unknown.");
184     const auto scale =
185             getScale(outputState.displaySpace.bounds, outputState.framebufferSpace.bounds);
186     outputState.framebufferSpace.content = outputState.displaySpace.content.scale(scale.x, scale.y);
187 
188     // Compute layerStackSpace
189     outputState.layerStackSpace.content = layerStackSpaceRect;
190     outputState.layerStackSpace.bounds = layerStackSpaceRect;
191 
192     outputState.transform = outputState.layerStackSpace.getTransform(outputState.displaySpace);
193     outputState.needsFiltering = outputState.transform.needsBilinearFiltering();
194     dirtyEntireOutput();
195 }
196 
setDisplaySize(const ui::Size & size)197 void Output::setDisplaySize(const ui::Size& size) {
198     mRenderSurface->setDisplaySize(size);
199 
200     auto& state = editState();
201 
202     // Update framebuffer space
203     const Rect newBounds(size);
204     state.framebufferSpace.bounds = newBounds;
205 
206     // Update display space
207     state.displaySpace.bounds = newBounds;
208     state.transform = state.layerStackSpace.getTransform(state.displaySpace);
209 
210     // Update oriented display space
211     const auto orientation = state.displaySpace.orientation;
212     ui::Size orientedSize = size;
213     if (orientation == ui::ROTATION_90 || orientation == ui::ROTATION_270) {
214         std::swap(orientedSize.width, orientedSize.height);
215     }
216     const Rect newOrientedBounds(orientedSize);
217     state.orientedDisplaySpace.bounds = newOrientedBounds;
218 
219     if (mPlanner) {
220         mPlanner->setDisplaySize(size);
221     }
222 
223     dirtyEntireOutput();
224 }
225 
getTransformHint() const226 ui::Transform::RotationFlags Output::getTransformHint() const {
227     return static_cast<ui::Transform::RotationFlags>(getState().transform.getOrientation());
228 }
229 
setLayerStackFilter(uint32_t layerStackId,bool isInternal)230 void Output::setLayerStackFilter(uint32_t layerStackId, bool isInternal) {
231     auto& outputState = editState();
232     outputState.layerStackId = layerStackId;
233     outputState.layerStackInternal = isInternal;
234 
235     dirtyEntireOutput();
236 }
237 
setColorTransform(const compositionengine::CompositionRefreshArgs & args)238 void Output::setColorTransform(const compositionengine::CompositionRefreshArgs& args) {
239     auto& colorTransformMatrix = editState().colorTransformMatrix;
240     if (!args.colorTransformMatrix || colorTransformMatrix == args.colorTransformMatrix) {
241         return;
242     }
243 
244     colorTransformMatrix = *args.colorTransformMatrix;
245 
246     dirtyEntireOutput();
247 }
248 
setColorProfile(const ColorProfile & colorProfile)249 void Output::setColorProfile(const ColorProfile& colorProfile) {
250     ui::Dataspace targetDataspace =
251             getDisplayColorProfile()->getTargetDataspace(colorProfile.mode, colorProfile.dataspace,
252                                                          colorProfile.colorSpaceAgnosticDataspace);
253 
254     auto& outputState = editState();
255     if (outputState.colorMode == colorProfile.mode &&
256         outputState.dataspace == colorProfile.dataspace &&
257         outputState.renderIntent == colorProfile.renderIntent &&
258         outputState.targetDataspace == targetDataspace) {
259         return;
260     }
261 
262     outputState.colorMode = colorProfile.mode;
263     outputState.dataspace = colorProfile.dataspace;
264     outputState.renderIntent = colorProfile.renderIntent;
265     outputState.targetDataspace = targetDataspace;
266 
267     mRenderSurface->setBufferDataspace(colorProfile.dataspace);
268 
269     ALOGV("Set active color mode: %s (%d), active render intent: %s (%d)",
270           decodeColorMode(colorProfile.mode).c_str(), colorProfile.mode,
271           decodeRenderIntent(colorProfile.renderIntent).c_str(), colorProfile.renderIntent);
272 
273     dirtyEntireOutput();
274 }
275 
setDisplayBrightness(float sdrWhitePointNits,float displayBrightnessNits)276 void Output::setDisplayBrightness(float sdrWhitePointNits, float displayBrightnessNits) {
277     auto& outputState = editState();
278     if (outputState.sdrWhitePointNits == sdrWhitePointNits &&
279         outputState.displayBrightnessNits == displayBrightnessNits) {
280         // Nothing changed
281         return;
282     }
283     outputState.sdrWhitePointNits = sdrWhitePointNits;
284     outputState.displayBrightnessNits = displayBrightnessNits;
285     dirtyEntireOutput();
286 }
287 
dump(std::string & out) const288 void Output::dump(std::string& out) const {
289     using android::base::StringAppendF;
290 
291     StringAppendF(&out, "   Composition Output State: [\"%s\"]", mName.c_str());
292 
293     out.append("\n   ");
294 
295     dumpBase(out);
296 }
297 
dumpBase(std::string & out) const298 void Output::dumpBase(std::string& out) const {
299     dumpState(out);
300 
301     if (mDisplayColorProfile) {
302         mDisplayColorProfile->dump(out);
303     } else {
304         out.append("    No display color profile!\n");
305     }
306 
307     if (mRenderSurface) {
308         mRenderSurface->dump(out);
309     } else {
310         out.append("    No render surface!\n");
311     }
312 
313     android::base::StringAppendF(&out, "\n   %zu Layers\n", getOutputLayerCount());
314     for (const auto* outputLayer : getOutputLayersOrderedByZ()) {
315         if (!outputLayer) {
316             continue;
317         }
318         outputLayer->dump(out);
319     }
320 }
321 
dumpPlannerInfo(const Vector<String16> & args,std::string & out) const322 void Output::dumpPlannerInfo(const Vector<String16>& args, std::string& out) const {
323     if (!mPlanner) {
324         base::StringAppendF(&out, "Planner is disabled\n");
325         return;
326     }
327     base::StringAppendF(&out, "Planner info for display [%s]\n", mName.c_str());
328     mPlanner->dump(args, out);
329 }
330 
getDisplayColorProfile() const331 compositionengine::DisplayColorProfile* Output::getDisplayColorProfile() const {
332     return mDisplayColorProfile.get();
333 }
334 
setDisplayColorProfile(std::unique_ptr<compositionengine::DisplayColorProfile> mode)335 void Output::setDisplayColorProfile(std::unique_ptr<compositionengine::DisplayColorProfile> mode) {
336     mDisplayColorProfile = std::move(mode);
337 }
338 
getReleasedLayersForTest() const339 const Output::ReleasedLayers& Output::getReleasedLayersForTest() const {
340     return mReleasedLayers;
341 }
342 
setDisplayColorProfileForTest(std::unique_ptr<compositionengine::DisplayColorProfile> mode)343 void Output::setDisplayColorProfileForTest(
344         std::unique_ptr<compositionengine::DisplayColorProfile> mode) {
345     mDisplayColorProfile = std::move(mode);
346 }
347 
getRenderSurface() const348 compositionengine::RenderSurface* Output::getRenderSurface() const {
349     return mRenderSurface.get();
350 }
351 
setRenderSurface(std::unique_ptr<compositionengine::RenderSurface> surface)352 void Output::setRenderSurface(std::unique_ptr<compositionengine::RenderSurface> surface) {
353     mRenderSurface = std::move(surface);
354     const auto size = mRenderSurface->getSize();
355     editState().framebufferSpace.bounds = Rect(size);
356     if (mPlanner) {
357         mPlanner->setDisplaySize(size);
358     }
359     dirtyEntireOutput();
360 }
361 
cacheClientCompositionRequests(uint32_t cacheSize)362 void Output::cacheClientCompositionRequests(uint32_t cacheSize) {
363     if (cacheSize == 0) {
364         mClientCompositionRequestCache.reset();
365     } else {
366         mClientCompositionRequestCache = std::make_unique<ClientCompositionRequestCache>(cacheSize);
367     }
368 };
369 
setRenderSurfaceForTest(std::unique_ptr<compositionengine::RenderSurface> surface)370 void Output::setRenderSurfaceForTest(std::unique_ptr<compositionengine::RenderSurface> surface) {
371     mRenderSurface = std::move(surface);
372 }
373 
getDirtyRegion(bool repaintEverything) const374 Region Output::getDirtyRegion(bool repaintEverything) const {
375     const auto& outputState = getState();
376     Region dirty(outputState.layerStackSpace.content);
377     if (!repaintEverything) {
378         dirty.andSelf(outputState.dirtyRegion);
379     }
380     return dirty;
381 }
382 
belongsInOutput(std::optional<uint32_t> layerStackId,bool internalOnly) const383 bool Output::belongsInOutput(std::optional<uint32_t> layerStackId, bool internalOnly) const {
384     // The layerStackId's must match, and also the layer must not be internal
385     // only when not on an internal output.
386     const auto& outputState = getState();
387     return layerStackId && (*layerStackId == outputState.layerStackId) &&
388             (!internalOnly || outputState.layerStackInternal);
389 }
390 
belongsInOutput(const sp<compositionengine::LayerFE> & layerFE) const391 bool Output::belongsInOutput(const sp<compositionengine::LayerFE>& layerFE) const {
392     const auto* layerFEState = layerFE->getCompositionState();
393     return layerFEState && belongsInOutput(layerFEState->layerStackId, layerFEState->internalOnly);
394 }
395 
createOutputLayer(const sp<LayerFE> & layerFE) const396 std::unique_ptr<compositionengine::OutputLayer> Output::createOutputLayer(
397         const sp<LayerFE>& layerFE) const {
398     return impl::createOutputLayer(*this, layerFE);
399 }
400 
getOutputLayerForLayer(const sp<LayerFE> & layerFE) const401 compositionengine::OutputLayer* Output::getOutputLayerForLayer(const sp<LayerFE>& layerFE) const {
402     auto index = findCurrentOutputLayerForLayer(layerFE);
403     return index ? getOutputLayerOrderedByZByIndex(*index) : nullptr;
404 }
405 
findCurrentOutputLayerForLayer(const sp<compositionengine::LayerFE> & layer) const406 std::optional<size_t> Output::findCurrentOutputLayerForLayer(
407         const sp<compositionengine::LayerFE>& layer) const {
408     for (size_t i = 0; i < getOutputLayerCount(); i++) {
409         auto outputLayer = getOutputLayerOrderedByZByIndex(i);
410         if (outputLayer && &outputLayer->getLayerFE() == layer.get()) {
411             return i;
412         }
413     }
414     return std::nullopt;
415 }
416 
setReleasedLayers(Output::ReleasedLayers && layers)417 void Output::setReleasedLayers(Output::ReleasedLayers&& layers) {
418     mReleasedLayers = std::move(layers);
419 }
420 
prepare(const compositionengine::CompositionRefreshArgs & refreshArgs,LayerFESet & geomSnapshots)421 void Output::prepare(const compositionengine::CompositionRefreshArgs& refreshArgs,
422                      LayerFESet& geomSnapshots) {
423     ATRACE_CALL();
424     ALOGV(__FUNCTION__);
425 
426     rebuildLayerStacks(refreshArgs, geomSnapshots);
427 }
428 
present(const compositionengine::CompositionRefreshArgs & refreshArgs)429 void Output::present(const compositionengine::CompositionRefreshArgs& refreshArgs) {
430     ATRACE_CALL();
431     ALOGV(__FUNCTION__);
432 
433     updateColorProfile(refreshArgs);
434     updateCompositionState(refreshArgs);
435     planComposition();
436     writeCompositionState(refreshArgs);
437     setColorTransform(refreshArgs);
438     beginFrame();
439     prepareFrame();
440     devOptRepaintFlash(refreshArgs);
441     finishFrame(refreshArgs);
442     postFramebuffer();
443     renderCachedSets(refreshArgs);
444 }
445 
rebuildLayerStacks(const compositionengine::CompositionRefreshArgs & refreshArgs,LayerFESet & layerFESet)446 void Output::rebuildLayerStacks(const compositionengine::CompositionRefreshArgs& refreshArgs,
447                                 LayerFESet& layerFESet) {
448     ATRACE_CALL();
449     ALOGV(__FUNCTION__);
450 
451     auto& outputState = editState();
452 
453     // Do nothing if this output is not enabled or there is no need to perform this update
454     if (!outputState.isEnabled || CC_LIKELY(!refreshArgs.updatingOutputGeometryThisFrame)) {
455         return;
456     }
457 
458     // Process the layers to determine visibility and coverage
459     compositionengine::Output::CoverageState coverage{layerFESet};
460     collectVisibleLayers(refreshArgs, coverage);
461 
462     // Compute the resulting coverage for this output, and store it for later
463     const ui::Transform& tr = outputState.transform;
464     Region undefinedRegion{outputState.displaySpace.bounds};
465     undefinedRegion.subtractSelf(tr.transform(coverage.aboveOpaqueLayers));
466 
467     outputState.undefinedRegion = undefinedRegion;
468     outputState.dirtyRegion.orSelf(coverage.dirtyRegion);
469 }
470 
collectVisibleLayers(const compositionengine::CompositionRefreshArgs & refreshArgs,compositionengine::Output::CoverageState & coverage)471 void Output::collectVisibleLayers(const compositionengine::CompositionRefreshArgs& refreshArgs,
472                                   compositionengine::Output::CoverageState& coverage) {
473     // Evaluate the layers from front to back to determine what is visible. This
474     // also incrementally calculates the coverage information for each layer as
475     // well as the entire output.
476     for (auto layer : reversed(refreshArgs.layers)) {
477         // Incrementally process the coverage for each layer
478         ensureOutputLayerIfVisible(layer, coverage);
479 
480         // TODO(b/121291683): Stop early if the output is completely covered and
481         // no more layers could even be visible underneath the ones on top.
482     }
483 
484     setReleasedLayers(refreshArgs);
485 
486     finalizePendingOutputLayers();
487 }
488 
ensureOutputLayerIfVisible(sp<compositionengine::LayerFE> & layerFE,compositionengine::Output::CoverageState & coverage)489 void Output::ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>& layerFE,
490                                         compositionengine::Output::CoverageState& coverage) {
491     // Ensure we have a snapshot of the basic geometry layer state. Limit the
492     // snapshots to once per frame for each candidate layer, as layers may
493     // appear on multiple outputs.
494     if (!coverage.latchedLayers.count(layerFE)) {
495         coverage.latchedLayers.insert(layerFE);
496         layerFE->prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry);
497     }
498 
499     // Only consider the layers on the given layer stack
500     if (!belongsInOutput(layerFE)) {
501         return;
502     }
503 
504     // Obtain a read-only pointer to the front-end layer state
505     const auto* layerFEState = layerFE->getCompositionState();
506     if (CC_UNLIKELY(!layerFEState)) {
507         return;
508     }
509 
510     // handle hidden surfaces by setting the visible region to empty
511     if (CC_UNLIKELY(!layerFEState->isVisible)) {
512         return;
513     }
514 
515     /*
516      * opaqueRegion: area of a surface that is fully opaque.
517      */
518     Region opaqueRegion;
519 
520     /*
521      * visibleRegion: area of a surface that is visible on screen and not fully
522      * transparent. This is essentially the layer's footprint minus the opaque
523      * regions above it. Areas covered by a translucent surface are considered
524      * visible.
525      */
526     Region visibleRegion;
527 
528     /*
529      * coveredRegion: area of a surface that is covered by all visible regions
530      * above it (which includes the translucent areas).
531      */
532     Region coveredRegion;
533 
534     /*
535      * transparentRegion: area of a surface that is hinted to be completely
536      * transparent. This is only used to tell when the layer has no visible non-
537      * transparent regions and can be removed from the layer list. It does not
538      * affect the visibleRegion of this layer or any layers beneath it. The hint
539      * may not be correct if apps don't respect the SurfaceView restrictions
540      * (which, sadly, some don't).
541      */
542     Region transparentRegion;
543 
544     /*
545      * shadowRegion: Region cast by the layer's shadow.
546      */
547     Region shadowRegion;
548 
549     const ui::Transform& tr = layerFEState->geomLayerTransform;
550 
551     // Get the visible region
552     // TODO(b/121291683): Is it worth creating helper methods on LayerFEState
553     // for computations like this?
554     const Rect visibleRect(tr.transform(layerFEState->geomLayerBounds));
555     visibleRegion.set(visibleRect);
556 
557     if (layerFEState->shadowRadius > 0.0f) {
558         // if the layer casts a shadow, offset the layers visible region and
559         // calculate the shadow region.
560         const auto inset = static_cast<int32_t>(ceilf(layerFEState->shadowRadius) * -1.0f);
561         Rect visibleRectWithShadows(visibleRect);
562         visibleRectWithShadows.inset(inset, inset, inset, inset);
563         visibleRegion.set(visibleRectWithShadows);
564         shadowRegion = visibleRegion.subtract(visibleRect);
565     }
566 
567     if (visibleRegion.isEmpty()) {
568         return;
569     }
570 
571     // Remove the transparent area from the visible region
572     if (!layerFEState->isOpaque) {
573         if (tr.preserveRects()) {
574             // transform the transparent region
575             transparentRegion = tr.transform(layerFEState->transparentRegionHint);
576         } else {
577             // transformation too complex, can't do the
578             // transparent region optimization.
579             transparentRegion.clear();
580         }
581     }
582 
583     // compute the opaque region
584     const auto layerOrientation = tr.getOrientation();
585     if (layerFEState->isOpaque && ((layerOrientation & ui::Transform::ROT_INVALID) == 0)) {
586         // If we one of the simple category of transforms (0/90/180/270 rotation
587         // + any flip), then the opaque region is the layer's footprint.
588         // Otherwise we don't try and compute the opaque region since there may
589         // be errors at the edges, and we treat the entire layer as
590         // translucent.
591         opaqueRegion.set(visibleRect);
592     }
593 
594     // Clip the covered region to the visible region
595     coveredRegion = coverage.aboveCoveredLayers.intersect(visibleRegion);
596 
597     // Update accumAboveCoveredLayers for next (lower) layer
598     coverage.aboveCoveredLayers.orSelf(visibleRegion);
599 
600     // subtract the opaque region covered by the layers above us
601     visibleRegion.subtractSelf(coverage.aboveOpaqueLayers);
602 
603     if (visibleRegion.isEmpty()) {
604         return;
605     }
606 
607     // Get coverage information for the layer as previously displayed,
608     // also taking over ownership from mOutputLayersorderedByZ.
609     auto prevOutputLayerIndex = findCurrentOutputLayerForLayer(layerFE);
610     auto prevOutputLayer =
611             prevOutputLayerIndex ? getOutputLayerOrderedByZByIndex(*prevOutputLayerIndex) : nullptr;
612 
613     //  Get coverage information for the layer as previously displayed
614     // TODO(b/121291683): Define kEmptyRegion as a constant in Region.h
615     const Region kEmptyRegion;
616     const Region& oldVisibleRegion =
617             prevOutputLayer ? prevOutputLayer->getState().visibleRegion : kEmptyRegion;
618     const Region& oldCoveredRegion =
619             prevOutputLayer ? prevOutputLayer->getState().coveredRegion : kEmptyRegion;
620 
621     // compute this layer's dirty region
622     Region dirty;
623     if (layerFEState->contentDirty) {
624         // we need to invalidate the whole region
625         dirty = visibleRegion;
626         // as well, as the old visible region
627         dirty.orSelf(oldVisibleRegion);
628     } else {
629         /* compute the exposed region:
630          *   the exposed region consists of two components:
631          *   1) what's VISIBLE now and was COVERED before
632          *   2) what's EXPOSED now less what was EXPOSED before
633          *
634          * note that (1) is conservative, we start with the whole visible region
635          * but only keep what used to be covered by something -- which mean it
636          * may have been exposed.
637          *
638          * (2) handles areas that were not covered by anything but got exposed
639          * because of a resize.
640          *
641          */
642         const Region newExposed = visibleRegion - coveredRegion;
643         const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
644         dirty = (visibleRegion & oldCoveredRegion) | (newExposed - oldExposed);
645     }
646     dirty.subtractSelf(coverage.aboveOpaqueLayers);
647 
648     // accumulate to the screen dirty region
649     coverage.dirtyRegion.orSelf(dirty);
650 
651     // Update accumAboveOpaqueLayers for next (lower) layer
652     coverage.aboveOpaqueLayers.orSelf(opaqueRegion);
653 
654     // Compute the visible non-transparent region
655     Region visibleNonTransparentRegion = visibleRegion.subtract(transparentRegion);
656 
657     // Perform the final check to see if this layer is visible on this output
658     // TODO(b/121291683): Why does this not use visibleRegion? (see outputSpaceVisibleRegion below)
659     const auto& outputState = getState();
660     Region drawRegion(outputState.transform.transform(visibleNonTransparentRegion));
661     drawRegion.andSelf(outputState.displaySpace.bounds);
662     if (drawRegion.isEmpty()) {
663         return;
664     }
665 
666     Region visibleNonShadowRegion = visibleRegion.subtract(shadowRegion);
667 
668     // The layer is visible. Either reuse the existing outputLayer if we have
669     // one, or create a new one if we do not.
670     auto result = ensureOutputLayer(prevOutputLayerIndex, layerFE);
671 
672     // Store the layer coverage information into the layer state as some of it
673     // is useful later.
674     auto& outputLayerState = result->editState();
675     outputLayerState.visibleRegion = visibleRegion;
676     outputLayerState.visibleNonTransparentRegion = visibleNonTransparentRegion;
677     outputLayerState.coveredRegion = coveredRegion;
678     outputLayerState.outputSpaceVisibleRegion = outputState.transform.transform(
679             visibleNonShadowRegion.intersect(outputState.layerStackSpace.content));
680     outputLayerState.shadowRegion = shadowRegion;
681 }
682 
setReleasedLayers(const compositionengine::CompositionRefreshArgs &)683 void Output::setReleasedLayers(const compositionengine::CompositionRefreshArgs&) {
684     // The base class does nothing with this call.
685 }
686 
updateLayerStateFromFE(const CompositionRefreshArgs & args) const687 void Output::updateLayerStateFromFE(const CompositionRefreshArgs& args) const {
688     for (auto* layer : getOutputLayersOrderedByZ()) {
689         layer->getLayerFE().prepareCompositionState(
690                 args.updatingGeometryThisFrame ? LayerFE::StateSubset::GeometryAndContent
691                                                : LayerFE::StateSubset::Content);
692     }
693 }
694 
updateCompositionState(const compositionengine::CompositionRefreshArgs & refreshArgs)695 void Output::updateCompositionState(const compositionengine::CompositionRefreshArgs& refreshArgs) {
696     ATRACE_CALL();
697     ALOGV(__FUNCTION__);
698 
699     if (!getState().isEnabled) {
700         return;
701     }
702 
703     mLayerRequestingBackgroundBlur = findLayerRequestingBackgroundComposition();
704     bool forceClientComposition = mLayerRequestingBackgroundBlur != nullptr;
705 
706     for (auto* layer : getOutputLayersOrderedByZ()) {
707         layer->updateCompositionState(refreshArgs.updatingGeometryThisFrame,
708                                       refreshArgs.devOptForceClientComposition ||
709                                               forceClientComposition,
710                                       refreshArgs.internalDisplayRotationFlags);
711 
712         if (mLayerRequestingBackgroundBlur == layer) {
713             forceClientComposition = false;
714         }
715     }
716 }
717 
planComposition()718 void Output::planComposition() {
719     if (!mPlanner || !getState().isEnabled) {
720         return;
721     }
722 
723     ATRACE_CALL();
724     ALOGV(__FUNCTION__);
725 
726     mPlanner->plan(getOutputLayersOrderedByZ());
727 }
728 
writeCompositionState(const compositionengine::CompositionRefreshArgs & refreshArgs)729 void Output::writeCompositionState(const compositionengine::CompositionRefreshArgs& refreshArgs) {
730     ATRACE_CALL();
731     ALOGV(__FUNCTION__);
732 
733     if (!getState().isEnabled) {
734         return;
735     }
736 
737     editState().earliestPresentTime = refreshArgs.earliestPresentTime;
738     editState().previousPresentFence = refreshArgs.previousPresentFence;
739 
740     compositionengine::OutputLayer* peekThroughLayer = nullptr;
741     sp<GraphicBuffer> previousOverride = nullptr;
742     bool includeGeometry = refreshArgs.updatingGeometryThisFrame;
743     uint32_t z = 0;
744     bool overrideZ = false;
745     for (auto* layer : getOutputLayersOrderedByZ()) {
746         if (layer == peekThroughLayer) {
747             // No longer needed, although it should not show up again, so
748             // resetting it is not truly needed either.
749             peekThroughLayer = nullptr;
750 
751             // peekThroughLayer was already drawn ahead of its z order.
752             continue;
753         }
754         bool skipLayer = false;
755         const auto& overrideInfo = layer->getState().overrideInfo;
756         if (overrideInfo.buffer != nullptr) {
757             if (previousOverride && overrideInfo.buffer->getBuffer() == previousOverride) {
758                 ALOGV("Skipping redundant buffer");
759                 skipLayer = true;
760             } else {
761                 // First layer with the override buffer.
762                 if (overrideInfo.peekThroughLayer) {
763                     peekThroughLayer = overrideInfo.peekThroughLayer;
764 
765                     // Draw peekThroughLayer first.
766                     overrideZ = true;
767                     includeGeometry = true;
768                     constexpr bool isPeekingThrough = true;
769                     peekThroughLayer->writeStateToHWC(includeGeometry, false, z++, overrideZ,
770                                                       isPeekingThrough);
771                 }
772 
773                 previousOverride = overrideInfo.buffer->getBuffer();
774             }
775         }
776 
777         constexpr bool isPeekingThrough = false;
778         layer->writeStateToHWC(includeGeometry, skipLayer, z++, overrideZ, isPeekingThrough);
779     }
780 }
781 
findLayerRequestingBackgroundComposition() const782 compositionengine::OutputLayer* Output::findLayerRequestingBackgroundComposition() const {
783     compositionengine::OutputLayer* layerRequestingBgComposition = nullptr;
784     for (auto* layer : getOutputLayersOrderedByZ()) {
785         auto* compState = layer->getLayerFE().getCompositionState();
786 
787         // If any layer has a sideband stream, we will disable blurs. In that case, we don't
788         // want to force client composition because of the blur.
789         if (compState->sidebandStream != nullptr) {
790             return nullptr;
791         }
792         if (compState->isOpaque) {
793             continue;
794         }
795         if (compState->backgroundBlurRadius > 0 || compState->blurRegions.size() > 0) {
796             layerRequestingBgComposition = layer;
797         }
798     }
799     return layerRequestingBgComposition;
800 }
801 
updateColorProfile(const compositionengine::CompositionRefreshArgs & refreshArgs)802 void Output::updateColorProfile(const compositionengine::CompositionRefreshArgs& refreshArgs) {
803     setColorProfile(pickColorProfile(refreshArgs));
804 }
805 
806 // Returns a data space that fits all visible layers.  The returned data space
807 // can only be one of
808 //  - Dataspace::SRGB (use legacy dataspace and let HWC saturate when colors are enhanced)
809 //  - Dataspace::DISPLAY_P3
810 //  - Dataspace::DISPLAY_BT2020
811 // The returned HDR data space is one of
812 //  - Dataspace::UNKNOWN
813 //  - Dataspace::BT2020_HLG
814 //  - Dataspace::BT2020_PQ
getBestDataspace(ui::Dataspace * outHdrDataSpace,bool * outIsHdrClientComposition) const815 ui::Dataspace Output::getBestDataspace(ui::Dataspace* outHdrDataSpace,
816                                        bool* outIsHdrClientComposition) const {
817     ui::Dataspace bestDataSpace = ui::Dataspace::V0_SRGB;
818     *outHdrDataSpace = ui::Dataspace::UNKNOWN;
819 
820     for (const auto* layer : getOutputLayersOrderedByZ()) {
821         switch (layer->getLayerFE().getCompositionState()->dataspace) {
822             case ui::Dataspace::V0_SCRGB:
823             case ui::Dataspace::V0_SCRGB_LINEAR:
824             case ui::Dataspace::BT2020:
825             case ui::Dataspace::BT2020_ITU:
826             case ui::Dataspace::BT2020_LINEAR:
827             case ui::Dataspace::DISPLAY_BT2020:
828                 bestDataSpace = ui::Dataspace::DISPLAY_BT2020;
829                 break;
830             case ui::Dataspace::DISPLAY_P3:
831                 bestDataSpace = ui::Dataspace::DISPLAY_P3;
832                 break;
833             case ui::Dataspace::BT2020_PQ:
834             case ui::Dataspace::BT2020_ITU_PQ:
835                 bestDataSpace = ui::Dataspace::DISPLAY_P3;
836                 *outHdrDataSpace = ui::Dataspace::BT2020_PQ;
837                 *outIsHdrClientComposition =
838                         layer->getLayerFE().getCompositionState()->forceClientComposition;
839                 break;
840             case ui::Dataspace::BT2020_HLG:
841             case ui::Dataspace::BT2020_ITU_HLG:
842                 bestDataSpace = ui::Dataspace::DISPLAY_P3;
843                 // When there's mixed PQ content and HLG content, we set the HDR
844                 // data space to be BT2020_PQ and convert HLG to PQ.
845                 if (*outHdrDataSpace == ui::Dataspace::UNKNOWN) {
846                     *outHdrDataSpace = ui::Dataspace::BT2020_HLG;
847                 }
848                 break;
849             default:
850                 break;
851         }
852     }
853 
854     return bestDataSpace;
855 }
856 
pickColorProfile(const compositionengine::CompositionRefreshArgs & refreshArgs) const857 compositionengine::Output::ColorProfile Output::pickColorProfile(
858         const compositionengine::CompositionRefreshArgs& refreshArgs) const {
859     if (refreshArgs.outputColorSetting == OutputColorSetting::kUnmanaged) {
860         return ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
861                             ui::RenderIntent::COLORIMETRIC,
862                             refreshArgs.colorSpaceAgnosticDataspace};
863     }
864 
865     ui::Dataspace hdrDataSpace;
866     bool isHdrClientComposition = false;
867     ui::Dataspace bestDataSpace = getBestDataspace(&hdrDataSpace, &isHdrClientComposition);
868 
869     switch (refreshArgs.forceOutputColorMode) {
870         case ui::ColorMode::SRGB:
871             bestDataSpace = ui::Dataspace::V0_SRGB;
872             break;
873         case ui::ColorMode::DISPLAY_P3:
874             bestDataSpace = ui::Dataspace::DISPLAY_P3;
875             break;
876         default:
877             break;
878     }
879 
880     // respect hdrDataSpace only when there is no legacy HDR support
881     const bool isHdr = hdrDataSpace != ui::Dataspace::UNKNOWN &&
882             !mDisplayColorProfile->hasLegacyHdrSupport(hdrDataSpace) && !isHdrClientComposition;
883     if (isHdr) {
884         bestDataSpace = hdrDataSpace;
885     }
886 
887     ui::RenderIntent intent;
888     switch (refreshArgs.outputColorSetting) {
889         case OutputColorSetting::kManaged:
890         case OutputColorSetting::kUnmanaged:
891             intent = isHdr ? ui::RenderIntent::TONE_MAP_COLORIMETRIC
892                            : ui::RenderIntent::COLORIMETRIC;
893             break;
894         case OutputColorSetting::kEnhanced:
895             intent = isHdr ? ui::RenderIntent::TONE_MAP_ENHANCE : ui::RenderIntent::ENHANCE;
896             break;
897         default: // vendor display color setting
898             intent = static_cast<ui::RenderIntent>(refreshArgs.outputColorSetting);
899             break;
900     }
901 
902     ui::ColorMode outMode;
903     ui::Dataspace outDataSpace;
904     ui::RenderIntent outRenderIntent;
905     mDisplayColorProfile->getBestColorMode(bestDataSpace, intent, &outDataSpace, &outMode,
906                                            &outRenderIntent);
907 
908     return ColorProfile{outMode, outDataSpace, outRenderIntent,
909                         refreshArgs.colorSpaceAgnosticDataspace};
910 }
911 
beginFrame()912 void Output::beginFrame() {
913     auto& outputState = editState();
914     const bool dirty = !getDirtyRegion(false).isEmpty();
915     const bool empty = getOutputLayerCount() == 0;
916     const bool wasEmpty = !outputState.lastCompositionHadVisibleLayers;
917 
918     // If nothing has changed (!dirty), don't recompose.
919     // If something changed, but we don't currently have any visible layers,
920     //   and didn't when we last did a composition, then skip it this time.
921     // The second rule does two things:
922     // - When all layers are removed from a display, we'll emit one black
923     //   frame, then nothing more until we get new layers.
924     // - When a display is created with a private layer stack, we won't
925     //   emit any black frames until a layer is added to the layer stack.
926     const bool mustRecompose = dirty && !(empty && wasEmpty);
927 
928     const char flagPrefix[] = {'-', '+'};
929     static_cast<void>(flagPrefix);
930     ALOGV_IF("%s: %s composition for %s (%cdirty %cempty %cwasEmpty)", __FUNCTION__,
931              mustRecompose ? "doing" : "skipping", getName().c_str(), flagPrefix[dirty],
932              flagPrefix[empty], flagPrefix[wasEmpty]);
933 
934     mRenderSurface->beginFrame(mustRecompose);
935 
936     if (mustRecompose) {
937         outputState.lastCompositionHadVisibleLayers = !empty;
938     }
939 }
940 
prepareFrame()941 void Output::prepareFrame() {
942     ATRACE_CALL();
943     ALOGV(__FUNCTION__);
944 
945     const auto& outputState = getState();
946     if (!outputState.isEnabled) {
947         return;
948     }
949 
950     chooseCompositionStrategy();
951 
952     if (mPlanner) {
953         mPlanner->reportFinalPlan(getOutputLayersOrderedByZ());
954     }
955 
956     mRenderSurface->prepareFrame(outputState.usesClientComposition,
957                                  outputState.usesDeviceComposition);
958 }
959 
devOptRepaintFlash(const compositionengine::CompositionRefreshArgs & refreshArgs)960 void Output::devOptRepaintFlash(const compositionengine::CompositionRefreshArgs& refreshArgs) {
961     if (CC_LIKELY(!refreshArgs.devOptFlashDirtyRegionsDelay)) {
962         return;
963     }
964 
965     if (getState().isEnabled) {
966         // transform the dirty region into this screen's coordinate space
967         const Region dirtyRegion = getDirtyRegion(refreshArgs.repaintEverything);
968         if (!dirtyRegion.isEmpty()) {
969             base::unique_fd readyFence;
970             // redraw the whole screen
971             static_cast<void>(composeSurfaces(dirtyRegion, refreshArgs));
972 
973             mRenderSurface->queueBuffer(std::move(readyFence));
974         }
975     }
976 
977     postFramebuffer();
978 
979     std::this_thread::sleep_for(*refreshArgs.devOptFlashDirtyRegionsDelay);
980 
981     prepareFrame();
982 }
983 
finishFrame(const compositionengine::CompositionRefreshArgs & refreshArgs)984 void Output::finishFrame(const compositionengine::CompositionRefreshArgs& refreshArgs) {
985     ATRACE_CALL();
986     ALOGV(__FUNCTION__);
987 
988     if (!getState().isEnabled) {
989         return;
990     }
991 
992     // Repaint the framebuffer (if needed), getting the optional fence for when
993     // the composition completes.
994     auto optReadyFence = composeSurfaces(Region::INVALID_REGION, refreshArgs);
995     if (!optReadyFence) {
996         return;
997     }
998 
999     // swap buffers (presentation)
1000     mRenderSurface->queueBuffer(std::move(*optReadyFence));
1001 }
1002 
composeSurfaces(const Region & debugRegion,const compositionengine::CompositionRefreshArgs & refreshArgs)1003 std::optional<base::unique_fd> Output::composeSurfaces(
1004         const Region& debugRegion, const compositionengine::CompositionRefreshArgs& refreshArgs) {
1005     ATRACE_CALL();
1006     ALOGV(__FUNCTION__);
1007 
1008     const auto& outputState = getState();
1009     OutputCompositionState& outputCompositionState = editState();
1010     const TracedOrdinal<bool> hasClientComposition = {"hasClientComposition",
1011                                                       outputState.usesClientComposition};
1012 
1013     auto& renderEngine = getCompositionEngine().getRenderEngine();
1014     const bool supportsProtectedContent = renderEngine.supportsProtectedContent();
1015 
1016     // If we the display is secure, protected content support is enabled, and at
1017     // least one layer has protected content, we need to use a secure back
1018     // buffer.
1019     if (outputState.isSecure && supportsProtectedContent) {
1020         auto layers = getOutputLayersOrderedByZ();
1021         bool needsProtected = std::any_of(layers.begin(), layers.end(), [](auto* layer) {
1022             return layer->getLayerFE().getCompositionState()->hasProtectedContent;
1023         });
1024         if (needsProtected != renderEngine.isProtected()) {
1025             renderEngine.useProtectedContext(needsProtected);
1026         }
1027         if (needsProtected != mRenderSurface->isProtected() &&
1028             needsProtected == renderEngine.isProtected()) {
1029             mRenderSurface->setProtected(needsProtected);
1030         }
1031     } else if (!outputState.isSecure && renderEngine.isProtected()) {
1032         renderEngine.useProtectedContext(false);
1033     }
1034 
1035     base::unique_fd fd;
1036 
1037     std::shared_ptr<renderengine::ExternalTexture> tex;
1038 
1039     // If we aren't doing client composition on this output, but do have a
1040     // flipClientTarget request for this frame on this output, we still need to
1041     // dequeue a buffer.
1042     if (hasClientComposition || outputState.flipClientTarget) {
1043         tex = mRenderSurface->dequeueBuffer(&fd);
1044         if (tex == nullptr) {
1045             ALOGW("Dequeuing buffer for display [%s] failed, bailing out of "
1046                   "client composition for this frame",
1047                   mName.c_str());
1048             return {};
1049         }
1050     }
1051 
1052     base::unique_fd readyFence;
1053     if (!hasClientComposition) {
1054         setExpensiveRenderingExpected(false);
1055         return readyFence;
1056     }
1057 
1058     ALOGV("hasClientComposition");
1059 
1060     renderengine::DisplaySettings clientCompositionDisplay;
1061     clientCompositionDisplay.physicalDisplay = outputState.framebufferSpace.content;
1062     clientCompositionDisplay.clip = outputState.layerStackSpace.content;
1063     clientCompositionDisplay.orientation =
1064             ui::Transform::toRotationFlags(outputState.displaySpace.orientation);
1065     clientCompositionDisplay.outputDataspace = mDisplayColorProfile->hasWideColorGamut()
1066             ? outputState.dataspace
1067             : ui::Dataspace::UNKNOWN;
1068 
1069     // If we have a valid current display brightness use that, otherwise fall back to the
1070     // display's max desired
1071     clientCompositionDisplay.maxLuminance = outputState.displayBrightnessNits > 0.f
1072             ? outputState.displayBrightnessNits
1073             : mDisplayColorProfile->getHdrCapabilities().getDesiredMaxLuminance();
1074     clientCompositionDisplay.sdrWhitePointNits = outputState.sdrWhitePointNits;
1075 
1076     // Compute the global color transform matrix.
1077     if (!outputState.usesDeviceComposition && !getSkipColorTransform()) {
1078         clientCompositionDisplay.colorTransform = outputState.colorTransformMatrix;
1079     }
1080 
1081     // Note: Updated by generateClientCompositionRequests
1082     clientCompositionDisplay.clearRegion = Region::INVALID_REGION;
1083 
1084     // Generate the client composition requests for the layers on this output.
1085     std::vector<LayerFE::LayerSettings> clientCompositionLayers =
1086             generateClientCompositionRequests(supportsProtectedContent,
1087                                               clientCompositionDisplay.clearRegion,
1088                                               clientCompositionDisplay.outputDataspace);
1089     appendRegionFlashRequests(debugRegion, clientCompositionLayers);
1090 
1091     // Check if the client composition requests were rendered into the provided graphic buffer. If
1092     // so, we can reuse the buffer and avoid client composition.
1093     if (mClientCompositionRequestCache) {
1094         if (mClientCompositionRequestCache->exists(tex->getBuffer()->getId(),
1095                                                    clientCompositionDisplay,
1096                                                    clientCompositionLayers)) {
1097             outputCompositionState.reusedClientComposition = true;
1098             setExpensiveRenderingExpected(false);
1099             return readyFence;
1100         }
1101         mClientCompositionRequestCache->add(tex->getBuffer()->getId(), clientCompositionDisplay,
1102                                             clientCompositionLayers);
1103     }
1104 
1105     // We boost GPU frequency here because there will be color spaces conversion
1106     // or complex GPU shaders and it's expensive. We boost the GPU frequency so that
1107     // GPU composition can finish in time. We must reset GPU frequency afterwards,
1108     // because high frequency consumes extra battery.
1109     const bool expensiveBlurs =
1110             refreshArgs.blursAreExpensive && mLayerRequestingBackgroundBlur != nullptr;
1111     const bool expensiveRenderingExpected =
1112             clientCompositionDisplay.outputDataspace == ui::Dataspace::DISPLAY_P3 || expensiveBlurs;
1113     if (expensiveRenderingExpected) {
1114         setExpensiveRenderingExpected(true);
1115     }
1116 
1117     std::vector<const renderengine::LayerSettings*> clientCompositionLayerPointers;
1118     clientCompositionLayerPointers.reserve(clientCompositionLayers.size());
1119     std::transform(clientCompositionLayers.begin(), clientCompositionLayers.end(),
1120                    std::back_inserter(clientCompositionLayerPointers),
1121                    [](LayerFE::LayerSettings& settings) -> renderengine::LayerSettings* {
1122                        return &settings;
1123                    });
1124 
1125     const nsecs_t renderEngineStart = systemTime();
1126     // Only use the framebuffer cache when rendering to an internal display
1127     // TODO(b/173560331): This is only to help mitigate memory leaks from virtual displays because
1128     // right now we don't have a concrete eviction policy for output buffers: GLESRenderEngine
1129     // bounds its framebuffer cache but Skia RenderEngine has no current policy. The best fix is
1130     // probably to encapsulate the output buffer into a structure that dispatches resource cleanup
1131     // over to RenderEngine, in which case this flag can be removed from the drawLayers interface.
1132     const bool useFramebufferCache = outputState.layerStackInternal;
1133     status_t status =
1134             renderEngine.drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, tex,
1135                                     useFramebufferCache, std::move(fd), &readyFence);
1136 
1137     if (status != NO_ERROR && mClientCompositionRequestCache) {
1138         // If rendering was not successful, remove the request from the cache.
1139         mClientCompositionRequestCache->remove(tex->getBuffer()->getId());
1140     }
1141 
1142     auto& timeStats = getCompositionEngine().getTimeStats();
1143     if (readyFence.get() < 0) {
1144         timeStats.recordRenderEngineDuration(renderEngineStart, systemTime());
1145     } else {
1146         timeStats.recordRenderEngineDuration(renderEngineStart,
1147                                              std::make_shared<FenceTime>(
1148                                                      new Fence(dup(readyFence.get()))));
1149     }
1150 
1151     return readyFence;
1152 }
1153 
generateClientCompositionRequests(bool supportsProtectedContent,Region & clearRegion,ui::Dataspace outputDataspace)1154 std::vector<LayerFE::LayerSettings> Output::generateClientCompositionRequests(
1155         bool supportsProtectedContent, Region& clearRegion, ui::Dataspace outputDataspace) {
1156     std::vector<LayerFE::LayerSettings> clientCompositionLayers;
1157     ALOGV("Rendering client layers");
1158 
1159     const auto& outputState = getState();
1160     const Region viewportRegion(outputState.layerStackSpace.content);
1161     bool firstLayer = true;
1162     // Used when a layer clears part of the buffer.
1163     Region stubRegion;
1164 
1165     bool disableBlurs = false;
1166     sp<GraphicBuffer> previousOverrideBuffer = nullptr;
1167 
1168     for (auto* layer : getOutputLayersOrderedByZ()) {
1169         const auto& layerState = layer->getState();
1170         const auto* layerFEState = layer->getLayerFE().getCompositionState();
1171         auto& layerFE = layer->getLayerFE();
1172 
1173         const Region clip(viewportRegion.intersect(layerState.visibleRegion));
1174         ALOGV("Layer: %s", layerFE.getDebugName());
1175         if (clip.isEmpty()) {
1176             ALOGV("  Skipping for empty clip");
1177             firstLayer = false;
1178             continue;
1179         }
1180 
1181         disableBlurs |= layerFEState->sidebandStream != nullptr;
1182 
1183         const bool clientComposition = layer->requiresClientComposition();
1184 
1185         // We clear the client target for non-client composed layers if
1186         // requested by the HWC. We skip this if the layer is not an opaque
1187         // rectangle, as by definition the layer must blend with whatever is
1188         // underneath. We also skip the first layer as the buffer target is
1189         // guaranteed to start out cleared.
1190         const bool clearClientComposition =
1191                 layerState.clearClientTarget && layerFEState->isOpaque && !firstLayer;
1192 
1193         ALOGV("  Composition type: client %d clear %d", clientComposition, clearClientComposition);
1194 
1195         // If the layer casts a shadow but the content casting the shadow is occluded, skip
1196         // composing the non-shadow content and only draw the shadows.
1197         const bool realContentIsVisible = clientComposition &&
1198                 !layerState.visibleRegion.subtract(layerState.shadowRegion).isEmpty();
1199 
1200         if (clientComposition || clearClientComposition) {
1201             std::vector<LayerFE::LayerSettings> results;
1202             if (layer->getState().overrideInfo.buffer != nullptr) {
1203                 if (layer->getState().overrideInfo.buffer->getBuffer() != previousOverrideBuffer) {
1204                     results = layer->getOverrideCompositionList();
1205                     previousOverrideBuffer = layer->getState().overrideInfo.buffer->getBuffer();
1206                     ALOGV("Replacing [%s] with override in RE", layer->getLayerFE().getDebugName());
1207                 } else {
1208                     ALOGV("Skipping redundant override buffer for [%s] in RE",
1209                           layer->getLayerFE().getDebugName());
1210                 }
1211             } else {
1212                 LayerFE::ClientCompositionTargetSettings::BlurSetting blurSetting = disableBlurs
1213                         ? LayerFE::ClientCompositionTargetSettings::BlurSetting::Disabled
1214                         : (layer->getState().overrideInfo.disableBackgroundBlur
1215                                    ? LayerFE::ClientCompositionTargetSettings::BlurSetting::
1216                                              BlurRegionsOnly
1217                                    : LayerFE::ClientCompositionTargetSettings::BlurSetting::
1218                                              Enabled);
1219                 compositionengine::LayerFE::ClientCompositionTargetSettings
1220                         targetSettings{.clip = clip,
1221                                        .needsFiltering = layer->needsFiltering() ||
1222                                                outputState.needsFiltering,
1223                                        .isSecure = outputState.isSecure,
1224                                        .supportsProtectedContent = supportsProtectedContent,
1225                                        .clearRegion = clientComposition ? clearRegion : stubRegion,
1226                                        .viewport = outputState.layerStackSpace.content,
1227                                        .dataspace = outputDataspace,
1228                                        .realContentIsVisible = realContentIsVisible,
1229                                        .clearContent = !clientComposition,
1230                                        .blurSetting = blurSetting};
1231                 results = layerFE.prepareClientCompositionList(targetSettings);
1232                 if (realContentIsVisible && !results.empty()) {
1233                     layer->editState().clientCompositionTimestamp = systemTime();
1234                 }
1235             }
1236 
1237             clientCompositionLayers.insert(clientCompositionLayers.end(),
1238                                            std::make_move_iterator(results.begin()),
1239                                            std::make_move_iterator(results.end()));
1240             results.clear();
1241         }
1242 
1243         firstLayer = false;
1244     }
1245 
1246     return clientCompositionLayers;
1247 }
1248 
appendRegionFlashRequests(const Region & flashRegion,std::vector<LayerFE::LayerSettings> & clientCompositionLayers)1249 void Output::appendRegionFlashRequests(
1250         const Region& flashRegion, std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
1251     if (flashRegion.isEmpty()) {
1252         return;
1253     }
1254 
1255     LayerFE::LayerSettings layerSettings;
1256     layerSettings.source.buffer.buffer = nullptr;
1257     layerSettings.source.solidColor = half3(1.0, 0.0, 1.0);
1258     layerSettings.alpha = half(1.0);
1259 
1260     for (const auto& rect : flashRegion) {
1261         layerSettings.geometry.boundaries = rect.toFloatRect();
1262         clientCompositionLayers.push_back(layerSettings);
1263     }
1264 }
1265 
setExpensiveRenderingExpected(bool)1266 void Output::setExpensiveRenderingExpected(bool) {
1267     // The base class does nothing with this call.
1268 }
1269 
postFramebuffer()1270 void Output::postFramebuffer() {
1271     ATRACE_CALL();
1272     ALOGV(__FUNCTION__);
1273 
1274     if (!getState().isEnabled) {
1275         return;
1276     }
1277 
1278     auto& outputState = editState();
1279     outputState.dirtyRegion.clear();
1280     mRenderSurface->flip();
1281 
1282     auto frame = presentAndGetFrameFences();
1283 
1284     mRenderSurface->onPresentDisplayCompleted();
1285 
1286     for (auto* layer : getOutputLayersOrderedByZ()) {
1287         // The layer buffer from the previous frame (if any) is released
1288         // by HWC only when the release fence from this frame (if any) is
1289         // signaled.  Always get the release fence from HWC first.
1290         sp<Fence> releaseFence = Fence::NO_FENCE;
1291 
1292         if (auto hwcLayer = layer->getHwcLayer()) {
1293             if (auto f = frame.layerFences.find(hwcLayer); f != frame.layerFences.end()) {
1294                 releaseFence = f->second;
1295             }
1296         }
1297 
1298         // If the layer was client composited in the previous frame, we
1299         // need to merge with the previous client target acquire fence.
1300         // Since we do not track that, always merge with the current
1301         // client target acquire fence when it is available, even though
1302         // this is suboptimal.
1303         // TODO(b/121291683): Track previous frame client target acquire fence.
1304         if (outputState.usesClientComposition) {
1305             releaseFence =
1306                     Fence::merge("LayerRelease", releaseFence, frame.clientTargetAcquireFence);
1307         }
1308 
1309         layer->getLayerFE().onLayerDisplayed(releaseFence);
1310     }
1311 
1312     // We've got a list of layers needing fences, that are disjoint with
1313     // OutputLayersOrderedByZ.  The best we can do is to
1314     // supply them with the present fence.
1315     for (auto& weakLayer : mReleasedLayers) {
1316         if (auto layer = weakLayer.promote(); layer != nullptr) {
1317             layer->onLayerDisplayed(frame.presentFence);
1318         }
1319     }
1320 
1321     // Clear out the released layers now that we're done with them.
1322     mReleasedLayers.clear();
1323 }
1324 
renderCachedSets(const CompositionRefreshArgs & refreshArgs)1325 void Output::renderCachedSets(const CompositionRefreshArgs& refreshArgs) {
1326     if (mPlanner) {
1327         mPlanner->renderCachedSets(getState(), refreshArgs.nextInvalidateTime);
1328     }
1329 }
1330 
dirtyEntireOutput()1331 void Output::dirtyEntireOutput() {
1332     auto& outputState = editState();
1333     outputState.dirtyRegion.set(outputState.displaySpace.bounds);
1334 }
1335 
chooseCompositionStrategy()1336 void Output::chooseCompositionStrategy() {
1337     // The base output implementation can only do client composition
1338     auto& outputState = editState();
1339     outputState.usesClientComposition = true;
1340     outputState.usesDeviceComposition = false;
1341     outputState.reusedClientComposition = false;
1342 }
1343 
getSkipColorTransform() const1344 bool Output::getSkipColorTransform() const {
1345     return true;
1346 }
1347 
presentAndGetFrameFences()1348 compositionengine::Output::FrameFences Output::presentAndGetFrameFences() {
1349     compositionengine::Output::FrameFences result;
1350     if (getState().usesClientComposition) {
1351         result.clientTargetAcquireFence = mRenderSurface->getClientTargetAcquireFence();
1352     }
1353     return result;
1354 }
1355 
1356 } // namespace impl
1357 } // namespace android::compositionengine
1358