xref: /aosp_15_r20/frameworks/native/libs/gui/BufferItemConsumer.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright (C) 2012 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 #define LOG_TAG "BufferItemConsumer"
19 //#define ATRACE_TAG ATRACE_TAG_GRAPHICS
20 #include <utils/Log.h>
21 
22 #include <inttypes.h>
23 
24 #include <com_android_graphics_libgui_flags.h>
25 #include <gui/BufferItem.h>
26 #include <gui/BufferItemConsumer.h>
27 #include <ui/BufferQueueDefs.h>
28 #include <ui/GraphicBuffer.h>
29 
30 #define BI_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__)
31 // #define BI_LOGD(x, ...) ALOGD("[%s] " x, mName.c_str(), ##__VA_ARGS__)
32 // #define BI_LOGI(x, ...) ALOGI("[%s] " x, mName.c_str(), ##__VA_ARGS__)
33 // #define BI_LOGW(x, ...) ALOGW("[%s] " x, mName.c_str(), ##__VA_ARGS__)
34 #define BI_LOGE(x, ...) ALOGE("[%s] " x, mName.c_str(), ##__VA_ARGS__)
35 
36 namespace android {
37 
38 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
BufferItemConsumer(uint64_t consumerUsage,int bufferCount,bool controlledByApp,bool isConsumerSurfaceFlinger)39 BufferItemConsumer::BufferItemConsumer(uint64_t consumerUsage, int bufferCount,
40                                        bool controlledByApp, bool isConsumerSurfaceFlinger)
41       : ConsumerBase(controlledByApp, isConsumerSurfaceFlinger) {
42     initialize(consumerUsage, bufferCount);
43 }
44 
BufferItemConsumer(const sp<IGraphicBufferProducer> & producer,const sp<IGraphicBufferConsumer> & consumer,uint64_t consumerUsage,int bufferCount,bool controlledByApp)45 BufferItemConsumer::BufferItemConsumer(const sp<IGraphicBufferProducer>& producer,
46                                        const sp<IGraphicBufferConsumer>& consumer,
47                                        uint64_t consumerUsage, int bufferCount,
48                                        bool controlledByApp)
49       : ConsumerBase(producer, consumer, controlledByApp) {
50     initialize(consumerUsage, bufferCount);
51 }
52 #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
53 
BufferItemConsumer(const sp<IGraphicBufferConsumer> & consumer,uint64_t consumerUsage,int bufferCount,bool controlledByApp)54 BufferItemConsumer::BufferItemConsumer(
55         const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage,
56         int bufferCount, bool controlledByApp) :
57     ConsumerBase(consumer, controlledByApp)
58 {
59     initialize(consumerUsage, bufferCount);
60 }
61 
initialize(uint64_t consumerUsage,int bufferCount)62 void BufferItemConsumer::initialize(uint64_t consumerUsage, int bufferCount) {
63     status_t err = mConsumer->setConsumerUsageBits(consumerUsage);
64     LOG_ALWAYS_FATAL_IF(err != OK, "Failed to set consumer usage bits to %#" PRIx64, consumerUsage);
65     if (bufferCount != DEFAULT_MAX_BUFFERS) {
66         err = mConsumer->setMaxAcquiredBufferCount(bufferCount);
67         LOG_ALWAYS_FATAL_IF(err != OK, "Failed to set max acquired buffer count to %d",
68                             bufferCount);
69     }
70 }
71 
~BufferItemConsumer()72 BufferItemConsumer::~BufferItemConsumer() {}
73 
setBufferFreedListener(const wp<BufferFreedListener> & listener)74 void BufferItemConsumer::setBufferFreedListener(
75         const wp<BufferFreedListener>& listener) {
76     Mutex::Autolock _l(mMutex);
77     mBufferFreedListener = listener;
78 }
79 
acquireBuffer(BufferItem * item,nsecs_t presentWhen,bool waitForFence)80 status_t BufferItemConsumer::acquireBuffer(BufferItem *item,
81         nsecs_t presentWhen, bool waitForFence) {
82     status_t err;
83 
84     if (!item) return BAD_VALUE;
85 
86     Mutex::Autolock _l(mMutex);
87 
88     err = acquireBufferLocked(item, presentWhen);
89     if (err != OK) {
90         if (err != NO_BUFFER_AVAILABLE) {
91             BI_LOGE("Error acquiring buffer: %s (%d)", strerror(err), err);
92         }
93         return err;
94     }
95 
96     if (waitForFence) {
97         err = item->mFence->waitForever("BufferItemConsumer::acquireBuffer");
98         if (err != OK) {
99             BI_LOGE("Failed to wait for fence of acquired buffer: %s (%d)",
100                     strerror(-err), err);
101             return err;
102         }
103     }
104 
105     item->mGraphicBuffer = mSlots[item->mSlot].mGraphicBuffer;
106 
107     return OK;
108 }
109 
releaseBuffer(const BufferItem & item,const sp<Fence> & releaseFence)110 status_t BufferItemConsumer::releaseBuffer(const BufferItem &item,
111         const sp<Fence>& releaseFence) {
112     Mutex::Autolock _l(mMutex);
113     return releaseBufferSlotLocked(item.mSlot, item.mGraphicBuffer, releaseFence);
114 }
115 
116 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
releaseBuffer(const sp<GraphicBuffer> & buffer,const sp<Fence> & releaseFence)117 status_t BufferItemConsumer::releaseBuffer(const sp<GraphicBuffer>& buffer,
118                                            const sp<Fence>& releaseFence) {
119     Mutex::Autolock _l(mMutex);
120 
121     if (buffer == nullptr) {
122         return BAD_VALUE;
123     }
124 
125     int slotIndex = getSlotForBufferLocked(buffer);
126     if (slotIndex == INVALID_BUFFER_SLOT) {
127         return BAD_VALUE;
128     }
129 
130     return releaseBufferSlotLocked(slotIndex, buffer, releaseFence);
131 }
132 #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
133 
releaseBufferSlotLocked(int slotIndex,const sp<GraphicBuffer> & buffer,const sp<Fence> & releaseFence)134 status_t BufferItemConsumer::releaseBufferSlotLocked(int slotIndex, const sp<GraphicBuffer>& buffer,
135                                                      const sp<Fence>& releaseFence) {
136     status_t err;
137 
138     err = addReleaseFenceLocked(slotIndex, buffer, releaseFence);
139     if (err != OK) {
140         BI_LOGE("Failed to addReleaseFenceLocked");
141     }
142 
143     err = releaseBufferLocked(slotIndex, buffer);
144     if (err != OK && err != IGraphicBufferConsumer::STALE_BUFFER_SLOT) {
145         BI_LOGE("Failed to release buffer: %s (%d)",
146                 strerror(-err), err);
147     }
148     return err;
149 }
150 
freeBufferLocked(int slotIndex)151 void BufferItemConsumer::freeBufferLocked(int slotIndex) {
152     sp<BufferFreedListener> listener = mBufferFreedListener.promote();
153     if (listener != nullptr && mSlots[slotIndex].mGraphicBuffer != nullptr) {
154         // Fire callback if we have a listener registered and the buffer being freed is valid.
155         BI_LOGV("actually calling onBufferFreed");
156         listener->onBufferFreed(mSlots[slotIndex].mGraphicBuffer);
157     }
158     ConsumerBase::freeBufferLocked(slotIndex);
159 }
160 
161 } // namespace android
162