blob: 3cd432cd2bf74d4b2c8e59a0651adcb3d84a372a [file] [log] [blame]
Vishnu Naire14c6b32022-08-06 04:20:15 +00001/*
2 * Copyright 2022 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// #define LOG_NDEBUG 0
18#undef LOG_TAG
Vishnu Nairc6384702023-07-31 12:22:20 -070019#define LOG_TAG "SurfaceFlinger"
Vishnu Naire14c6b32022-08-06 04:20:15 +000020#define ATRACE_TAG ATRACE_TAG_GRAPHICS
21
Vishnu Nairbe0ad902024-06-27 23:38:43 +000022#include <common/trace.h>
Vishnu Naire14c6b32022-08-06 04:20:15 +000023#include <gui/GLConsumer.h>
Vishnu Naire14c6b32022-08-06 04:20:15 +000024#include <math/vec3.h>
25#include <system/window.h>
Vishnu Naire14c6b32022-08-06 04:20:15 +000026
Vishnu Naire14c6b32022-08-06 04:20:15 +000027#include "LayerFE.h"
Leon Scroggins III85d4b222023-05-09 13:58:18 -040028#include "SurfaceFlinger.h"
Melody Hsu793f8362024-01-08 20:00:35 +000029#include "ui/FenceResult.h"
Vishnu Naire14c6b32022-08-06 04:20:15 +000030
31namespace android {
32
33namespace {
34constexpr float defaultMaxLuminance = 1000.0;
35
36constexpr mat4 inverseOrientation(uint32_t transform) {
37 const mat4 flipH(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1);
38 const mat4 flipV(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1);
39 const mat4 rot90(0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1);
40 mat4 tr;
41
42 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
43 tr = tr * rot90;
44 }
45 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
46 tr = tr * flipH;
47 }
48 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) {
49 tr = tr * flipV;
50 }
51 return inverse(tr);
52}
53
54FloatRect reduce(const FloatRect& win, const Region& exclude) {
55 if (CC_LIKELY(exclude.isEmpty())) {
56 return win;
57 }
58 // Convert through Rect (by rounding) for lack of FloatRegion
59 return Region(Rect{win}).subtract(exclude).getBounds().toFloatRect();
60}
61
62// Computes the transform matrix using the setFilteringEnabled to determine whether the
63// transform matrix should be computed for use with bilinear filtering.
64void getDrawingTransformMatrix(const std::shared_ptr<renderengine::ExternalTexture>& buffer,
65 Rect bufferCrop, uint32_t bufferTransform, bool filteringEnabled,
66 float outMatrix[16]) {
67 if (!buffer) {
68 ALOGE("Buffer should not be null!");
69 return;
70 }
71 GLConsumer::computeTransformMatrix(outMatrix, static_cast<float>(buffer->getWidth()),
72 static_cast<float>(buffer->getHeight()),
73 buffer->getPixelFormat(), bufferCrop, bufferTransform,
74 filteringEnabled);
75}
76
77} // namespace
78
79LayerFE::LayerFE(const std::string& name) : mName(name) {}
80
Melody Hsu5aeb8162024-03-25 22:09:10 +000081LayerFE::~LayerFE() {
82 // Ensures that no promise is left unfulfilled before the LayerFE is destroyed.
83 // An unfulfilled promise could occur when a screenshot is attempted, but the
84 // render area is invalid and there is no memory for the capture result.
Melody Hsu0077fde2024-10-17 21:42:50 +000085 if (mReleaseFencePromiseStatus == ReleaseFencePromiseStatus::INITIALIZED) {
Melody Hsu5aeb8162024-03-25 22:09:10 +000086 setReleaseFence(Fence::NO_FENCE);
87 }
88}
89
Vishnu Naire14c6b32022-08-06 04:20:15 +000090const compositionengine::LayerFECompositionState* LayerFE::getCompositionState() const {
91 return mSnapshot.get();
92}
93
Melody Hsuc949cde2024-03-12 01:43:34 +000094bool LayerFE::onPreComposition(bool) {
Vishnu Naire14c6b32022-08-06 04:20:15 +000095 return mSnapshot->hasReadyFrame;
96}
97
98std::optional<compositionengine::LayerFE::LayerSettings> LayerFE::prepareClientComposition(
99 compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
100 std::optional<compositionengine::LayerFE::LayerSettings> layerSettings =
101 prepareClientCompositionInternal(targetSettings);
102 // Nothing to render.
103 if (!layerSettings) {
104 return {};
105 }
106
107 // HWC requests to clear this layer.
108 if (targetSettings.clearContent) {
109 prepareClearClientComposition(*layerSettings, false /* blackout */);
110 return layerSettings;
111 }
112
113 // set the shadow for the layer if needed
114 prepareShadowClientComposition(*layerSettings, targetSettings.viewport);
115
YCairn Overturf65fb1c62025-02-24 22:57:09 +0000116 layerSettings->borderSettings = mSnapshot->borderSettings;
117
Vishnu Naire14c6b32022-08-06 04:20:15 +0000118 return layerSettings;
119}
120
121std::optional<compositionengine::LayerFE::LayerSettings> LayerFE::prepareClientCompositionInternal(
122 compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
Vishnu Nairbe0ad902024-06-27 23:38:43 +0000123 SFTRACE_CALL();
Vishnu Naire14c6b32022-08-06 04:20:15 +0000124 compositionengine::LayerFE::LayerSettings layerSettings;
YCairn Overturf65fb1c62025-02-24 22:57:09 +0000125 layerSettings.geometry.originalBounds = mSnapshot->geomLayerBounds;
Vishnu Naire14c6b32022-08-06 04:20:15 +0000126 layerSettings.geometry.boundaries =
127 reduce(mSnapshot->geomLayerBounds, mSnapshot->transparentRegionHint);
128 layerSettings.geometry.positionTransform = mSnapshot->geomLayerTransform.asMatrix4();
129
130 // skip drawing content if the targetSettings indicate the content will be occluded
131 const bool drawContent = targetSettings.realContentIsVisible || targetSettings.clearContent;
132 layerSettings.skipContentDraw = !drawContent;
133
134 if (!mSnapshot->colorTransformIsIdentity) {
135 layerSettings.colorTransform = mSnapshot->colorTransform;
136 }
137
138 const auto& roundedCornerState = mSnapshot->roundedCorner;
139 layerSettings.geometry.roundedCornersRadius = roundedCornerState.radius;
140 layerSettings.geometry.roundedCornersCrop = roundedCornerState.cropRect;
141
142 layerSettings.alpha = mSnapshot->alpha;
143 layerSettings.sourceDataspace = mSnapshot->dataspace;
144
145 // Override the dataspace transfer from 170M to sRGB if the device configuration requests this.
146 // We do this here instead of in buffer info so that dumpsys can still report layers that are
147 // using the 170M transfer.
148 if (targetSettings.treat170mAsSrgb &&
149 (layerSettings.sourceDataspace & HAL_DATASPACE_TRANSFER_MASK) ==
150 HAL_DATASPACE_TRANSFER_SMPTE_170M) {
151 layerSettings.sourceDataspace = static_cast<ui::Dataspace>(
152 (layerSettings.sourceDataspace & HAL_DATASPACE_STANDARD_MASK) |
153 (layerSettings.sourceDataspace & HAL_DATASPACE_RANGE_MASK) |
154 HAL_DATASPACE_TRANSFER_SRGB);
155 }
156
157 layerSettings.whitePointNits = targetSettings.whitePointNits;
158 switch (targetSettings.blurSetting) {
159 case LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled:
160 layerSettings.backgroundBlurRadius = mSnapshot->backgroundBlurRadius;
161 layerSettings.blurRegions = mSnapshot->blurRegions;
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000162 layerSettings.blurRegionTransform = mSnapshot->localTransformInverse.asMatrix4();
Vishnu Naire14c6b32022-08-06 04:20:15 +0000163 break;
164 case LayerFE::ClientCompositionTargetSettings::BlurSetting::BackgroundBlurOnly:
165 layerSettings.backgroundBlurRadius = mSnapshot->backgroundBlurRadius;
166 break;
167 case LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly:
168 layerSettings.blurRegions = mSnapshot->blurRegions;
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000169 layerSettings.blurRegionTransform = mSnapshot->localTransformInverse.asMatrix4();
Vishnu Naire14c6b32022-08-06 04:20:15 +0000170 break;
171 case LayerFE::ClientCompositionTargetSettings::BlurSetting::Disabled:
172 default:
173 break;
174 }
175 layerSettings.stretchEffect = mSnapshot->stretchEffect;
Marzia Favarodcc9d9b2024-01-10 10:17:00 +0000176 layerSettings.edgeExtensionEffect = mSnapshot->edgeExtensionEffect;
Vishnu Naire14c6b32022-08-06 04:20:15 +0000177 // Record the name of the layer for debugging further down the stack.
178 layerSettings.name = mSnapshot->name;
Sally Qi1ed7dec2025-01-09 22:01:04 -0800179 layerSettings.luts = mSnapshot->luts ? mSnapshot->luts : targetSettings.luts;
Vishnu Naire14c6b32022-08-06 04:20:15 +0000180
181 if (hasEffect() && !hasBufferOrSidebandStream()) {
182 prepareEffectsClientComposition(layerSettings, targetSettings);
183 return layerSettings;
184 }
185
186 prepareBufferStateClientComposition(layerSettings, targetSettings);
187 return layerSettings;
188}
189
190void LayerFE::prepareClearClientComposition(LayerFE::LayerSettings& layerSettings,
191 bool blackout) const {
192 layerSettings.source.buffer.buffer = nullptr;
193 layerSettings.source.solidColor = half3(0.0f, 0.0f, 0.0f);
194 layerSettings.disableBlending = true;
195 layerSettings.bufferId = 0;
196 layerSettings.frameNumber = 0;
Sally Qi10fc8992024-12-03 22:10:45 -0800197 layerSettings.sequence = -1;
Vishnu Naire14c6b32022-08-06 04:20:15 +0000198
199 // If layer is blacked out, force alpha to 1 so that we draw a black color layer.
200 layerSettings.alpha = blackout ? 1.0f : 0.0f;
201 layerSettings.name = mSnapshot->name;
202}
203
204void LayerFE::prepareEffectsClientComposition(
205 compositionengine::LayerFE::LayerSettings& layerSettings,
206 compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
207 // If fill bounds are occluded or the fill color is invalid skip the fill settings.
208 if (targetSettings.realContentIsVisible && fillsColor()) {
209 // Set color for color fill settings.
210 layerSettings.source.solidColor = mSnapshot->color.rgb;
YCairn Overturf65fb1c62025-02-24 22:57:09 +0000211 } else if (hasBlur() || drawShadows() || hasOutline()) {
Vishnu Naire14c6b32022-08-06 04:20:15 +0000212 layerSettings.skipContentDraw = true;
213 }
214}
215
216void LayerFE::prepareBufferStateClientComposition(
217 compositionengine::LayerFE::LayerSettings& layerSettings,
218 compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
Vishnu Nairbe0ad902024-06-27 23:38:43 +0000219 SFTRACE_CALL();
Vishnu Naire14c6b32022-08-06 04:20:15 +0000220 if (CC_UNLIKELY(!mSnapshot->externalTexture)) {
221 // If there is no buffer for the layer or we have sidebandstream where there is no
222 // activeBuffer, then we need to return LayerSettings.
223 return;
224 }
Chavi Weingarten18fa7c62023-11-28 21:16:03 +0000225 bool blackOutLayer;
226 if (FlagManager::getInstance().display_protected()) {
227 blackOutLayer = (mSnapshot->hasProtectedContent && !targetSettings.isProtected) ||
228 (mSnapshot->isSecure && !targetSettings.isSecure);
229 } else {
230 blackOutLayer = (mSnapshot->hasProtectedContent && !targetSettings.isProtected) ||
231 ((mSnapshot->isSecure || mSnapshot->hasProtectedContent) &&
232 !targetSettings.isSecure);
233 }
Vishnu Naire14c6b32022-08-06 04:20:15 +0000234 const bool bufferCanBeUsedAsHwTexture =
235 mSnapshot->externalTexture->getUsage() & GraphicBuffer::USAGE_HW_TEXTURE;
236 if (blackOutLayer || !bufferCanBeUsedAsHwTexture) {
237 ALOGE_IF(!bufferCanBeUsedAsHwTexture, "%s is blacked out as buffer is not gpu readable",
238 mSnapshot->name.c_str());
239 prepareClearClientComposition(layerSettings, true /* blackout */);
240 return;
241 }
242
243 layerSettings.source.buffer.buffer = mSnapshot->externalTexture;
244 layerSettings.source.buffer.isOpaque = mSnapshot->contentOpaque;
245 layerSettings.source.buffer.fence = mSnapshot->acquireFence;
Vishnu Naire14c6b32022-08-06 04:20:15 +0000246 layerSettings.source.buffer.usePremultipliedAlpha = mSnapshot->premultipliedAlpha;
Vishnu Naire14c6b32022-08-06 04:20:15 +0000247 bool hasSmpte2086 = mSnapshot->hdrMetadata.validTypes & HdrMetadata::SMPTE2086;
248 bool hasCta861_3 = mSnapshot->hdrMetadata.validTypes & HdrMetadata::CTA861_3;
249 float maxLuminance = 0.f;
250 if (hasSmpte2086 && hasCta861_3) {
251 maxLuminance = std::min(mSnapshot->hdrMetadata.smpte2086.maxLuminance,
252 mSnapshot->hdrMetadata.cta8613.maxContentLightLevel);
253 } else if (hasSmpte2086) {
254 maxLuminance = mSnapshot->hdrMetadata.smpte2086.maxLuminance;
255 } else if (hasCta861_3) {
256 maxLuminance = mSnapshot->hdrMetadata.cta8613.maxContentLightLevel;
257 } else {
258 switch (layerSettings.sourceDataspace & HAL_DATASPACE_TRANSFER_MASK) {
259 case HAL_DATASPACE_TRANSFER_ST2084:
260 case HAL_DATASPACE_TRANSFER_HLG:
261 // Behavior-match previous releases for HDR content
262 maxLuminance = defaultMaxLuminance;
263 break;
264 }
265 }
266 layerSettings.source.buffer.maxLuminanceNits = maxLuminance;
267 layerSettings.frameNumber = mSnapshot->frameNumber;
268 layerSettings.bufferId = mSnapshot->externalTexture->getId();
Sally Qi10fc8992024-12-03 22:10:45 -0800269 layerSettings.sequence = mSnapshot->sequence;
Vishnu Naire14c6b32022-08-06 04:20:15 +0000270
Sally Qi380ac3e2023-10-10 20:27:02 +0000271 const bool useFiltering = targetSettings.needsFiltering ||
272 mSnapshot->geomLayerTransform.needsBilinearFiltering();
273
Vishnu Naire14c6b32022-08-06 04:20:15 +0000274 // Query the texture matrix given our current filtering mode.
275 float textureMatrix[16];
276 getDrawingTransformMatrix(layerSettings.source.buffer.buffer, mSnapshot->geomContentCrop,
Sally Qi380ac3e2023-10-10 20:27:02 +0000277 mSnapshot->geomBufferTransform, useFiltering,
Patrick Williams278a88f2023-01-27 16:52:40 -0600278 textureMatrix);
Vishnu Naire14c6b32022-08-06 04:20:15 +0000279
280 if (mSnapshot->geomBufferUsesDisplayInverseTransform) {
281 /*
282 * the code below applies the primary display's inverse transform to
283 * the texture transform
284 */
Leon Scroggins III85d4b222023-05-09 13:58:18 -0400285 uint32_t transform = SurfaceFlinger::getActiveDisplayRotationFlags();
Vishnu Naire14c6b32022-08-06 04:20:15 +0000286 mat4 tr = inverseOrientation(transform);
287
288 /**
289 * TODO(b/36727915): This is basically a hack.
290 *
291 * Ensure that regardless of the parent transformation,
292 * this buffer is always transformed from native display
293 * orientation to display orientation. For example, in the case
294 * of a camera where the buffer remains in native orientation,
295 * we want the pixels to always be upright.
296 */
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000297 const auto parentTransform = mSnapshot->parentTransform;
Vishnu Naire14c6b32022-08-06 04:20:15 +0000298 tr = tr * inverseOrientation(parentTransform.getOrientation());
299
300 // and finally apply it to the original texture matrix
301 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
302 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
303 }
304
305 const Rect win{layerSettings.geometry.boundaries};
306 float bufferWidth = static_cast<float>(mSnapshot->bufferSize.getWidth());
307 float bufferHeight = static_cast<float>(mSnapshot->bufferSize.getHeight());
308
309 // Layers can have a "buffer size" of [0, 0, -1, -1] when no display frame has
310 // been set and there is no parent layer bounds. In that case, the scale is meaningless so
311 // ignore them.
312 if (!mSnapshot->bufferSize.isValid()) {
313 bufferWidth = float(win.right) - float(win.left);
314 bufferHeight = float(win.bottom) - float(win.top);
315 }
316
317 const float scaleHeight = (float(win.bottom) - float(win.top)) / bufferHeight;
318 const float scaleWidth = (float(win.right) - float(win.left)) / bufferWidth;
319 const float translateY = float(win.top) / bufferHeight;
320 const float translateX = float(win.left) / bufferWidth;
321
322 // Flip y-coordinates because GLConsumer expects OpenGL convention.
323 mat4 tr = mat4::translate(vec4(.5f, .5f, 0.f, 1.f)) * mat4::scale(vec4(1.f, -1.f, 1.f, 1.f)) *
324 mat4::translate(vec4(-.5f, -.5f, 0.f, 1.f)) *
325 mat4::translate(vec4(translateX, translateY, 0.f, 1.f)) *
326 mat4::scale(vec4(scaleWidth, scaleHeight, 1.0f, 1.0f));
327
Sally Qi380ac3e2023-10-10 20:27:02 +0000328 layerSettings.source.buffer.useTextureFiltering = useFiltering;
Vishnu Naire14c6b32022-08-06 04:20:15 +0000329 layerSettings.source.buffer.textureTransform =
330 mat4(static_cast<const float*>(textureMatrix)) * tr;
331
332 return;
333}
334
335void LayerFE::prepareShadowClientComposition(LayerFE::LayerSettings& caster,
336 const Rect& layerStackRect) const {
Vishnu Naird9e4f462023-10-06 04:05:45 +0000337 ShadowSettings state = mSnapshot->shadowSettings;
Vishnu Naire14c6b32022-08-06 04:20:15 +0000338 if (state.length <= 0.f || (state.ambientColor.a <= 0.f && state.spotColor.a <= 0.f)) {
339 return;
340 }
341
342 // Shift the spot light x-position to the middle of the display and then
343 // offset it by casting layer's screen pos.
344 state.lightPos.x =
345 (static_cast<float>(layerStackRect.width()) / 2.f) - mSnapshot->transformedBounds.left;
346 state.lightPos.y -= mSnapshot->transformedBounds.top;
347 caster.shadow = state;
348}
349
Brian Lindahlf5fdff82024-11-01 09:28:47 -0600350void LayerFE::onPictureProfileCommitted() {
351 mCompositionResult.wasPictureProfileCommitted = true;
352 mCompositionResult.pictureProfileHandle = mSnapshot->pictureProfileHandle;
353}
354
355CompositionResult LayerFE::stealCompositionResult() {
356 CompositionResult result;
357 std::swap(mCompositionResult, result);
358 return result;
Vishnu Naire14c6b32022-08-06 04:20:15 +0000359}
360
361const char* LayerFE::getDebugName() const {
362 return mName.c_str();
363}
364
365const LayerMetadata* LayerFE::getMetadata() const {
366 return &mSnapshot->layerMetadata;
367}
368
369const LayerMetadata* LayerFE::getRelativeMetadata() const {
370 return &mSnapshot->relativeLayerMetadata;
371}
372
373int32_t LayerFE::getSequence() const {
Vishnu Nair269f69d2023-09-08 11:45:26 -0700374 return static_cast<int32_t>(mSnapshot->uniqueSequence);
Vishnu Naire14c6b32022-08-06 04:20:15 +0000375}
376
377bool LayerFE::hasRoundedCorners() const {
378 return mSnapshot->roundedCorner.hasRoundedCorners();
379}
380
381void LayerFE::setWasClientComposed(const sp<Fence>& fence) {
382 mCompositionResult.lastClientCompositionFence = fence;
383}
384
385bool LayerFE::hasBufferOrSidebandStream() const {
386 return mSnapshot->externalTexture || mSnapshot->sidebandStream;
387}
388
389bool LayerFE::fillsColor() const {
390 return mSnapshot->color.r >= 0.0_hf && mSnapshot->color.g >= 0.0_hf &&
391 mSnapshot->color.b >= 0.0_hf;
392}
393
394bool LayerFE::hasBlur() const {
395 return mSnapshot->backgroundBlurRadius > 0 || mSnapshot->blurRegions.size() > 0;
396}
397
YCairn Overturf65fb1c62025-02-24 22:57:09 +0000398bool LayerFE::hasOutline() const {
399 return mSnapshot->borderSettings.strokeWidth > 0;
400}
401
Vishnu Naire14c6b32022-08-06 04:20:15 +0000402bool LayerFE::drawShadows() const {
403 return mSnapshot->shadowSettings.length > 0.f &&
404 (mSnapshot->shadowSettings.ambientColor.a > 0 ||
405 mSnapshot->shadowSettings.spotColor.a > 0);
406};
407
408const sp<GraphicBuffer> LayerFE::getBuffer() const {
409 return mSnapshot->externalTexture ? mSnapshot->externalTexture->getBuffer() : nullptr;
410}
411
Melody Hsu793f8362024-01-08 20:00:35 +0000412void LayerFE::setReleaseFence(const FenceResult& releaseFence) {
413 // Promises should not be fulfilled more than once. This case can occur if virtual
414 // displays with the same layerstack ID are being created and destroyed in quick
415 // succession, such as in tests. This would result in a race condition in which
416 // multiple displays have the same layerstack ID within the same vsync interval.
417 if (mReleaseFencePromiseStatus == ReleaseFencePromiseStatus::FULFILLED) {
418 return;
419 }
Alec Mouridf868ba2025-02-25 16:08:19 -0800420
421 if (releaseFence.has_value()) {
422 if (FlagManager::getInstance().monitor_buffer_fences()) {
423 if (auto strongBuffer = mReleasedBuffer.promote()) {
424 strongBuffer->getDependencyMonitor()
425 .addAccessCompletion(FenceTime::makeValid(releaseFence.value()), "HWC");
426 }
427 }
428 }
Melody Hsu793f8362024-01-08 20:00:35 +0000429 mReleaseFence.set_value(releaseFence);
430 mReleaseFencePromiseStatus = ReleaseFencePromiseStatus::FULFILLED;
431}
432
433// LayerFEs are reused and a new fence needs to be created whevever a buffer is latched.
434ftl::Future<FenceResult> LayerFE::createReleaseFenceFuture() {
435 if (mReleaseFencePromiseStatus == ReleaseFencePromiseStatus::INITIALIZED) {
436 LOG_ALWAYS_FATAL("Attempting to create a new promise while one is still unfulfilled.");
437 }
438 mReleaseFence = std::promise<FenceResult>();
439 mReleaseFencePromiseStatus = ReleaseFencePromiseStatus::INITIALIZED;
440 return mReleaseFence.get_future();
441}
442
443LayerFE::ReleaseFencePromiseStatus LayerFE::getReleaseFencePromiseStatus() {
444 return mReleaseFencePromiseStatus;
445}
Vishnu Nair734f2882024-12-19 17:04:57 -0800446
Alec Mouridf868ba2025-02-25 16:08:19 -0800447void LayerFE::setReleasedBuffer(sp<GraphicBuffer> buffer) {
448 mReleasedBuffer = std::move(buffer);
449}
450
Cairn Overturfad9d5142025-02-05 11:11:50 -0800451void LayerFE::setLastHwcState(const LayerFE::HwcLayerDebugState &state) {
452 mLastHwcState = state;
Vishnu Nair734f2882024-12-19 17:04:57 -0800453}
454
Cairn Overturfad9d5142025-02-05 11:11:50 -0800455const LayerFE::HwcLayerDebugState& LayerFE::getLastHwcState() const {
456 return mLastHwcState;
457};
Vishnu Nair734f2882024-12-19 17:04:57 -0800458
Vishnu Naire14c6b32022-08-06 04:20:15 +0000459} // namespace android