xref: /aosp_15_r20/frameworks/native/libs/nativedisplay/surfacetexture/SurfaceTexture.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2019 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #include <cutils/compiler.h>
18*38e8c45fSAndroid Build Coastguard Worker #include <gui/BufferQueue.h>
19*38e8c45fSAndroid Build Coastguard Worker #include <surfacetexture/ImageConsumer.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <surfacetexture/SurfaceTexture.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <surfacetexture/surface_texture_platform.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <math/mat4.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <system/window.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <utils/Trace.h>
25*38e8c45fSAndroid Build Coastguard Worker 
26*38e8c45fSAndroid Build Coastguard Worker #include <com_android_graphics_libgui_flags.h>
27*38e8c45fSAndroid Build Coastguard Worker 
28*38e8c45fSAndroid Build Coastguard Worker namespace android {
29*38e8c45fSAndroid Build Coastguard Worker 
30*38e8c45fSAndroid Build Coastguard Worker // Macros for including the SurfaceTexture name in log messages
31*38e8c45fSAndroid Build Coastguard Worker #define SFT_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__)
32*38e8c45fSAndroid Build Coastguard Worker #define SFT_LOGD(x, ...) ALOGD("[%s] " x, mName.c_str(), ##__VA_ARGS__)
33*38e8c45fSAndroid Build Coastguard Worker #define SFT_LOGW(x, ...) ALOGW("[%s] " x, mName.c_str(), ##__VA_ARGS__)
34*38e8c45fSAndroid Build Coastguard Worker #define SFT_LOGE(x, ...) ALOGE("[%s] " x, mName.c_str(), ##__VA_ARGS__)
35*38e8c45fSAndroid Build Coastguard Worker 
36*38e8c45fSAndroid Build Coastguard Worker static const mat4 mtxIdentity;
37*38e8c45fSAndroid Build Coastguard Worker 
38*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
SurfaceTexture(uint32_t tex,uint32_t texTarget,bool useFenceSync,bool isControlledByApp)39*38e8c45fSAndroid Build Coastguard Worker SurfaceTexture::SurfaceTexture(uint32_t tex, uint32_t texTarget, bool useFenceSync,
40*38e8c45fSAndroid Build Coastguard Worker                                bool isControlledByApp)
41*38e8c45fSAndroid Build Coastguard Worker       : ConsumerBase(isControlledByApp),
42*38e8c45fSAndroid Build Coastguard Worker         mCurrentCrop(Rect::EMPTY_RECT),
43*38e8c45fSAndroid Build Coastguard Worker         mCurrentTransform(0),
44*38e8c45fSAndroid Build Coastguard Worker         mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
45*38e8c45fSAndroid Build Coastguard Worker         mCurrentFence(Fence::NO_FENCE),
46*38e8c45fSAndroid Build Coastguard Worker         mCurrentTimestamp(0),
47*38e8c45fSAndroid Build Coastguard Worker         mCurrentDataSpace(HAL_DATASPACE_UNKNOWN),
48*38e8c45fSAndroid Build Coastguard Worker         mCurrentFrameNumber(0),
49*38e8c45fSAndroid Build Coastguard Worker         mDefaultWidth(1),
50*38e8c45fSAndroid Build Coastguard Worker         mDefaultHeight(1),
51*38e8c45fSAndroid Build Coastguard Worker         mFilteringEnabled(true),
52*38e8c45fSAndroid Build Coastguard Worker         mTexName(tex),
53*38e8c45fSAndroid Build Coastguard Worker         mUseFenceSync(useFenceSync),
54*38e8c45fSAndroid Build Coastguard Worker         mTexTarget(texTarget),
55*38e8c45fSAndroid Build Coastguard Worker         mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),
56*38e8c45fSAndroid Build Coastguard Worker         mOpMode(OpMode::attachedToGL) {
57*38e8c45fSAndroid Build Coastguard Worker     initialize();
58*38e8c45fSAndroid Build Coastguard Worker }
59*38e8c45fSAndroid Build Coastguard Worker 
SurfaceTexture(uint32_t texTarget,bool useFenceSync,bool isControlledByApp)60*38e8c45fSAndroid Build Coastguard Worker SurfaceTexture::SurfaceTexture(uint32_t texTarget, bool useFenceSync, bool isControlledByApp)
61*38e8c45fSAndroid Build Coastguard Worker       : ConsumerBase(isControlledByApp),
62*38e8c45fSAndroid Build Coastguard Worker         mCurrentCrop(Rect::EMPTY_RECT),
63*38e8c45fSAndroid Build Coastguard Worker         mCurrentTransform(0),
64*38e8c45fSAndroid Build Coastguard Worker         mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
65*38e8c45fSAndroid Build Coastguard Worker         mCurrentFence(Fence::NO_FENCE),
66*38e8c45fSAndroid Build Coastguard Worker         mCurrentTimestamp(0),
67*38e8c45fSAndroid Build Coastguard Worker         mCurrentDataSpace(HAL_DATASPACE_UNKNOWN),
68*38e8c45fSAndroid Build Coastguard Worker         mCurrentFrameNumber(0),
69*38e8c45fSAndroid Build Coastguard Worker         mDefaultWidth(1),
70*38e8c45fSAndroid Build Coastguard Worker         mDefaultHeight(1),
71*38e8c45fSAndroid Build Coastguard Worker         mFilteringEnabled(true),
72*38e8c45fSAndroid Build Coastguard Worker         mTexName(0),
73*38e8c45fSAndroid Build Coastguard Worker         mUseFenceSync(useFenceSync),
74*38e8c45fSAndroid Build Coastguard Worker         mTexTarget(texTarget),
75*38e8c45fSAndroid Build Coastguard Worker         mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),
76*38e8c45fSAndroid Build Coastguard Worker         mOpMode(OpMode::detached) {
77*38e8c45fSAndroid Build Coastguard Worker     initialize();
78*38e8c45fSAndroid Build Coastguard Worker }
79*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
80*38e8c45fSAndroid Build Coastguard Worker 
SurfaceTexture(const sp<IGraphicBufferConsumer> & bq,uint32_t tex,uint32_t texTarget,bool useFenceSync,bool isControlledByApp)81*38e8c45fSAndroid Build Coastguard Worker SurfaceTexture::SurfaceTexture(const sp<IGraphicBufferConsumer>& bq, uint32_t tex,
82*38e8c45fSAndroid Build Coastguard Worker                                uint32_t texTarget, bool useFenceSync, bool isControlledByApp)
83*38e8c45fSAndroid Build Coastguard Worker       : ConsumerBase(bq, isControlledByApp),
84*38e8c45fSAndroid Build Coastguard Worker         mCurrentCrop(Rect::EMPTY_RECT),
85*38e8c45fSAndroid Build Coastguard Worker         mCurrentTransform(0),
86*38e8c45fSAndroid Build Coastguard Worker         mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
87*38e8c45fSAndroid Build Coastguard Worker         mCurrentFence(Fence::NO_FENCE),
88*38e8c45fSAndroid Build Coastguard Worker         mCurrentTimestamp(0),
89*38e8c45fSAndroid Build Coastguard Worker         mCurrentDataSpace(HAL_DATASPACE_UNKNOWN),
90*38e8c45fSAndroid Build Coastguard Worker         mCurrentFrameNumber(0),
91*38e8c45fSAndroid Build Coastguard Worker         mDefaultWidth(1),
92*38e8c45fSAndroid Build Coastguard Worker         mDefaultHeight(1),
93*38e8c45fSAndroid Build Coastguard Worker         mFilteringEnabled(true),
94*38e8c45fSAndroid Build Coastguard Worker         mTexName(tex),
95*38e8c45fSAndroid Build Coastguard Worker         mUseFenceSync(useFenceSync),
96*38e8c45fSAndroid Build Coastguard Worker         mTexTarget(texTarget),
97*38e8c45fSAndroid Build Coastguard Worker         mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),
98*38e8c45fSAndroid Build Coastguard Worker         mOpMode(OpMode::attachedToGL) {
99*38e8c45fSAndroid Build Coastguard Worker     initialize();
100*38e8c45fSAndroid Build Coastguard Worker }
101*38e8c45fSAndroid Build Coastguard Worker 
SurfaceTexture(const sp<IGraphicBufferConsumer> & bq,uint32_t texTarget,bool useFenceSync,bool isControlledByApp)102*38e8c45fSAndroid Build Coastguard Worker SurfaceTexture::SurfaceTexture(const sp<IGraphicBufferConsumer>& bq, uint32_t texTarget,
103*38e8c45fSAndroid Build Coastguard Worker                                bool useFenceSync, bool isControlledByApp)
104*38e8c45fSAndroid Build Coastguard Worker       : ConsumerBase(bq, isControlledByApp),
105*38e8c45fSAndroid Build Coastguard Worker         mCurrentCrop(Rect::EMPTY_RECT),
106*38e8c45fSAndroid Build Coastguard Worker         mCurrentTransform(0),
107*38e8c45fSAndroid Build Coastguard Worker         mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
108*38e8c45fSAndroid Build Coastguard Worker         mCurrentFence(Fence::NO_FENCE),
109*38e8c45fSAndroid Build Coastguard Worker         mCurrentTimestamp(0),
110*38e8c45fSAndroid Build Coastguard Worker         mCurrentDataSpace(HAL_DATASPACE_UNKNOWN),
111*38e8c45fSAndroid Build Coastguard Worker         mCurrentFrameNumber(0),
112*38e8c45fSAndroid Build Coastguard Worker         mDefaultWidth(1),
113*38e8c45fSAndroid Build Coastguard Worker         mDefaultHeight(1),
114*38e8c45fSAndroid Build Coastguard Worker         mFilteringEnabled(true),
115*38e8c45fSAndroid Build Coastguard Worker         mTexName(0),
116*38e8c45fSAndroid Build Coastguard Worker         mUseFenceSync(useFenceSync),
117*38e8c45fSAndroid Build Coastguard Worker         mTexTarget(texTarget),
118*38e8c45fSAndroid Build Coastguard Worker         mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),
119*38e8c45fSAndroid Build Coastguard Worker         mOpMode(OpMode::detached) {
120*38e8c45fSAndroid Build Coastguard Worker     initialize();
121*38e8c45fSAndroid Build Coastguard Worker }
122*38e8c45fSAndroid Build Coastguard Worker 
setDefaultBufferSize(uint32_t w,uint32_t h)123*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h) {
124*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
125*38e8c45fSAndroid Build Coastguard Worker     if (mAbandoned) {
126*38e8c45fSAndroid Build Coastguard Worker         SFT_LOGE("setDefaultBufferSize: SurfaceTexture is abandoned!");
127*38e8c45fSAndroid Build Coastguard Worker         return NO_INIT;
128*38e8c45fSAndroid Build Coastguard Worker     }
129*38e8c45fSAndroid Build Coastguard Worker     mDefaultWidth = w;
130*38e8c45fSAndroid Build Coastguard Worker     mDefaultHeight = h;
131*38e8c45fSAndroid Build Coastguard Worker     return mConsumer->setDefaultBufferSize(w, h);
132*38e8c45fSAndroid Build Coastguard Worker }
133*38e8c45fSAndroid Build Coastguard Worker 
updateTexImage()134*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceTexture::updateTexImage() {
135*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
136*38e8c45fSAndroid Build Coastguard Worker     SFT_LOGV("updateTexImage");
137*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
138*38e8c45fSAndroid Build Coastguard Worker 
139*38e8c45fSAndroid Build Coastguard Worker     if (mAbandoned) {
140*38e8c45fSAndroid Build Coastguard Worker         SFT_LOGE("updateTexImage: SurfaceTexture is abandoned!");
141*38e8c45fSAndroid Build Coastguard Worker         return NO_INIT;
142*38e8c45fSAndroid Build Coastguard Worker     }
143*38e8c45fSAndroid Build Coastguard Worker 
144*38e8c45fSAndroid Build Coastguard Worker     return mEGLConsumer.updateTexImage(*this);
145*38e8c45fSAndroid Build Coastguard Worker }
146*38e8c45fSAndroid Build Coastguard Worker 
releaseTexImage()147*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceTexture::releaseTexImage() {
148*38e8c45fSAndroid Build Coastguard Worker     // releaseTexImage can be invoked even when not attached to a GL context.
149*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
150*38e8c45fSAndroid Build Coastguard Worker     SFT_LOGV("releaseTexImage");
151*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
152*38e8c45fSAndroid Build Coastguard Worker 
153*38e8c45fSAndroid Build Coastguard Worker     if (mAbandoned) {
154*38e8c45fSAndroid Build Coastguard Worker         SFT_LOGE("releaseTexImage: SurfaceTexture is abandoned!");
155*38e8c45fSAndroid Build Coastguard Worker         return NO_INIT;
156*38e8c45fSAndroid Build Coastguard Worker     }
157*38e8c45fSAndroid Build Coastguard Worker 
158*38e8c45fSAndroid Build Coastguard Worker     return mEGLConsumer.releaseTexImage(*this);
159*38e8c45fSAndroid Build Coastguard Worker }
160*38e8c45fSAndroid Build Coastguard Worker 
acquireBufferLocked(BufferItem * item,nsecs_t presentWhen,uint64_t maxFrameNumber)161*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceTexture::acquireBufferLocked(BufferItem* item, nsecs_t presentWhen,
162*38e8c45fSAndroid Build Coastguard Worker                                              uint64_t maxFrameNumber) {
163*38e8c45fSAndroid Build Coastguard Worker     status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen, maxFrameNumber);
164*38e8c45fSAndroid Build Coastguard Worker     if (err != NO_ERROR) {
165*38e8c45fSAndroid Build Coastguard Worker         return err;
166*38e8c45fSAndroid Build Coastguard Worker     }
167*38e8c45fSAndroid Build Coastguard Worker 
168*38e8c45fSAndroid Build Coastguard Worker     switch (mOpMode) {
169*38e8c45fSAndroid Build Coastguard Worker         case OpMode::attachedToConsumer:
170*38e8c45fSAndroid Build Coastguard Worker             break;
171*38e8c45fSAndroid Build Coastguard Worker         case OpMode::attachedToGL:
172*38e8c45fSAndroid Build Coastguard Worker             mEGLConsumer.onAcquireBufferLocked(item, *this);
173*38e8c45fSAndroid Build Coastguard Worker             break;
174*38e8c45fSAndroid Build Coastguard Worker         case OpMode::detached:
175*38e8c45fSAndroid Build Coastguard Worker             break;
176*38e8c45fSAndroid Build Coastguard Worker     }
177*38e8c45fSAndroid Build Coastguard Worker 
178*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
179*38e8c45fSAndroid Build Coastguard Worker }
180*38e8c45fSAndroid Build Coastguard Worker 
releaseBufferLocked(int buf,sp<GraphicBuffer> graphicBuffer,EGLDisplay display,EGLSyncKHR eglFence)181*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceTexture::releaseBufferLocked(int buf, sp<GraphicBuffer> graphicBuffer,
182*38e8c45fSAndroid Build Coastguard Worker                                              EGLDisplay display, EGLSyncKHR eglFence) {
183*38e8c45fSAndroid Build Coastguard Worker     // release the buffer if it hasn't already been discarded by the
184*38e8c45fSAndroid Build Coastguard Worker     // BufferQueue. This can happen, for example, when the producer of this
185*38e8c45fSAndroid Build Coastguard Worker     // buffer has reallocated the original buffer slot after this buffer
186*38e8c45fSAndroid Build Coastguard Worker     // was acquired.
187*38e8c45fSAndroid Build Coastguard Worker     status_t err = ConsumerBase::releaseBufferLocked(buf, graphicBuffer, display, eglFence);
188*38e8c45fSAndroid Build Coastguard Worker     // We could be releasing an EGL/Vulkan buffer, even if not currently
189*38e8c45fSAndroid Build Coastguard Worker     // attached to a GL context.
190*38e8c45fSAndroid Build Coastguard Worker     mImageConsumer.onReleaseBufferLocked(buf);
191*38e8c45fSAndroid Build Coastguard Worker     mEGLConsumer.onReleaseBufferLocked(buf);
192*38e8c45fSAndroid Build Coastguard Worker     return err;
193*38e8c45fSAndroid Build Coastguard Worker }
194*38e8c45fSAndroid Build Coastguard Worker 
detachFromContext()195*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceTexture::detachFromContext() {
196*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
197*38e8c45fSAndroid Build Coastguard Worker     SFT_LOGV("detachFromContext");
198*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
199*38e8c45fSAndroid Build Coastguard Worker 
200*38e8c45fSAndroid Build Coastguard Worker     if (mAbandoned) {
201*38e8c45fSAndroid Build Coastguard Worker         SFT_LOGE("detachFromContext: abandoned SurfaceTexture");
202*38e8c45fSAndroid Build Coastguard Worker         return NO_INIT;
203*38e8c45fSAndroid Build Coastguard Worker     }
204*38e8c45fSAndroid Build Coastguard Worker 
205*38e8c45fSAndroid Build Coastguard Worker     if (mOpMode != OpMode::attachedToGL) {
206*38e8c45fSAndroid Build Coastguard Worker         SFT_LOGE("detachFromContext: SurfaceTexture is not attached to a GL context");
207*38e8c45fSAndroid Build Coastguard Worker         return INVALID_OPERATION;
208*38e8c45fSAndroid Build Coastguard Worker     }
209*38e8c45fSAndroid Build Coastguard Worker 
210*38e8c45fSAndroid Build Coastguard Worker     status_t err = mEGLConsumer.detachFromContext(*this);
211*38e8c45fSAndroid Build Coastguard Worker     if (err == OK) {
212*38e8c45fSAndroid Build Coastguard Worker         mOpMode = OpMode::detached;
213*38e8c45fSAndroid Build Coastguard Worker     }
214*38e8c45fSAndroid Build Coastguard Worker 
215*38e8c45fSAndroid Build Coastguard Worker     return err;
216*38e8c45fSAndroid Build Coastguard Worker }
217*38e8c45fSAndroid Build Coastguard Worker 
attachToContext(uint32_t tex)218*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceTexture::attachToContext(uint32_t tex) {
219*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
220*38e8c45fSAndroid Build Coastguard Worker     SFT_LOGV("attachToContext");
221*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
222*38e8c45fSAndroid Build Coastguard Worker 
223*38e8c45fSAndroid Build Coastguard Worker     if (mAbandoned) {
224*38e8c45fSAndroid Build Coastguard Worker         SFT_LOGE("attachToContext: abandoned SurfaceTexture");
225*38e8c45fSAndroid Build Coastguard Worker         return NO_INIT;
226*38e8c45fSAndroid Build Coastguard Worker     }
227*38e8c45fSAndroid Build Coastguard Worker 
228*38e8c45fSAndroid Build Coastguard Worker     if (mOpMode != OpMode::detached) {
229*38e8c45fSAndroid Build Coastguard Worker         SFT_LOGE("attachToContext: SurfaceTexture is already attached to a "
230*38e8c45fSAndroid Build Coastguard Worker                  "context");
231*38e8c45fSAndroid Build Coastguard Worker         return INVALID_OPERATION;
232*38e8c45fSAndroid Build Coastguard Worker     }
233*38e8c45fSAndroid Build Coastguard Worker 
234*38e8c45fSAndroid Build Coastguard Worker     return mEGLConsumer.attachToContext(tex, *this);
235*38e8c45fSAndroid Build Coastguard Worker }
236*38e8c45fSAndroid Build Coastguard Worker 
takeConsumerOwnership()237*38e8c45fSAndroid Build Coastguard Worker void SurfaceTexture::takeConsumerOwnership() {
238*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
239*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock _l(mMutex);
240*38e8c45fSAndroid Build Coastguard Worker     if (mAbandoned) {
241*38e8c45fSAndroid Build Coastguard Worker         SFT_LOGE("attachToView: abandoned SurfaceTexture");
242*38e8c45fSAndroid Build Coastguard Worker         return;
243*38e8c45fSAndroid Build Coastguard Worker     }
244*38e8c45fSAndroid Build Coastguard Worker     if (mOpMode == OpMode::detached) {
245*38e8c45fSAndroid Build Coastguard Worker         mOpMode = OpMode::attachedToConsumer;
246*38e8c45fSAndroid Build Coastguard Worker 
247*38e8c45fSAndroid Build Coastguard Worker         if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
248*38e8c45fSAndroid Build Coastguard Worker             // release possible EGLConsumer texture cache
249*38e8c45fSAndroid Build Coastguard Worker             mEGLConsumer.onFreeBufferLocked(mCurrentTexture);
250*38e8c45fSAndroid Build Coastguard Worker             mEGLConsumer.onAbandonLocked();
251*38e8c45fSAndroid Build Coastguard Worker         }
252*38e8c45fSAndroid Build Coastguard Worker     } else {
253*38e8c45fSAndroid Build Coastguard Worker         SFT_LOGE("attachToView: already attached");
254*38e8c45fSAndroid Build Coastguard Worker     }
255*38e8c45fSAndroid Build Coastguard Worker }
256*38e8c45fSAndroid Build Coastguard Worker 
releaseConsumerOwnership()257*38e8c45fSAndroid Build Coastguard Worker void SurfaceTexture::releaseConsumerOwnership() {
258*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
259*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock _l(mMutex);
260*38e8c45fSAndroid Build Coastguard Worker 
261*38e8c45fSAndroid Build Coastguard Worker     if (mAbandoned) {
262*38e8c45fSAndroid Build Coastguard Worker         SFT_LOGE("detachFromView: abandoned SurfaceTexture");
263*38e8c45fSAndroid Build Coastguard Worker         return;
264*38e8c45fSAndroid Build Coastguard Worker     }
265*38e8c45fSAndroid Build Coastguard Worker 
266*38e8c45fSAndroid Build Coastguard Worker     if (mOpMode == OpMode::attachedToConsumer) {
267*38e8c45fSAndroid Build Coastguard Worker         mOpMode = OpMode::detached;
268*38e8c45fSAndroid Build Coastguard Worker     } else {
269*38e8c45fSAndroid Build Coastguard Worker         SFT_LOGE("detachFromView: not attached to View");
270*38e8c45fSAndroid Build Coastguard Worker     }
271*38e8c45fSAndroid Build Coastguard Worker }
272*38e8c45fSAndroid Build Coastguard Worker 
getCurrentTextureTarget() const273*38e8c45fSAndroid Build Coastguard Worker uint32_t SurfaceTexture::getCurrentTextureTarget() const {
274*38e8c45fSAndroid Build Coastguard Worker     return mTexTarget;
275*38e8c45fSAndroid Build Coastguard Worker }
276*38e8c45fSAndroid Build Coastguard Worker 
getTransformMatrix(float mtx[16])277*38e8c45fSAndroid Build Coastguard Worker void SurfaceTexture::getTransformMatrix(float mtx[16]) {
278*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
279*38e8c45fSAndroid Build Coastguard Worker     memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix));
280*38e8c45fSAndroid Build Coastguard Worker }
281*38e8c45fSAndroid Build Coastguard Worker 
setFilteringEnabled(bool enabled)282*38e8c45fSAndroid Build Coastguard Worker void SurfaceTexture::setFilteringEnabled(bool enabled) {
283*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
284*38e8c45fSAndroid Build Coastguard Worker     if (mAbandoned) {
285*38e8c45fSAndroid Build Coastguard Worker         SFT_LOGE("setFilteringEnabled: SurfaceTexture is abandoned!");
286*38e8c45fSAndroid Build Coastguard Worker         return;
287*38e8c45fSAndroid Build Coastguard Worker     }
288*38e8c45fSAndroid Build Coastguard Worker     bool needsRecompute = mFilteringEnabled != enabled;
289*38e8c45fSAndroid Build Coastguard Worker     mFilteringEnabled = enabled;
290*38e8c45fSAndroid Build Coastguard Worker 
291*38e8c45fSAndroid Build Coastguard Worker     if (needsRecompute && mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT) {
292*38e8c45fSAndroid Build Coastguard Worker         SFT_LOGD("setFilteringEnabled called with no current item");
293*38e8c45fSAndroid Build Coastguard Worker     }
294*38e8c45fSAndroid Build Coastguard Worker 
295*38e8c45fSAndroid Build Coastguard Worker     if (needsRecompute && mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
296*38e8c45fSAndroid Build Coastguard Worker         computeCurrentTransformMatrixLocked();
297*38e8c45fSAndroid Build Coastguard Worker     }
298*38e8c45fSAndroid Build Coastguard Worker }
299*38e8c45fSAndroid Build Coastguard Worker 
computeCurrentTransformMatrixLocked()300*38e8c45fSAndroid Build Coastguard Worker void SurfaceTexture::computeCurrentTransformMatrixLocked() {
301*38e8c45fSAndroid Build Coastguard Worker     SFT_LOGV("computeCurrentTransformMatrixLocked");
302*38e8c45fSAndroid Build Coastguard Worker     sp<GraphicBuffer> buf = (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT)
303*38e8c45fSAndroid Build Coastguard Worker             ? nullptr
304*38e8c45fSAndroid Build Coastguard Worker             : mSlots[mCurrentTexture].mGraphicBuffer;
305*38e8c45fSAndroid Build Coastguard Worker     if (buf == nullptr) {
306*38e8c45fSAndroid Build Coastguard Worker         SFT_LOGD("computeCurrentTransformMatrixLocked: no current item");
307*38e8c45fSAndroid Build Coastguard Worker     }
308*38e8c45fSAndroid Build Coastguard Worker     computeTransformMatrix(mCurrentTransformMatrix, buf, mCurrentCrop, mCurrentTransform,
309*38e8c45fSAndroid Build Coastguard Worker                            mFilteringEnabled);
310*38e8c45fSAndroid Build Coastguard Worker }
311*38e8c45fSAndroid Build Coastguard Worker 
computeTransformMatrix(float outTransform[16],const sp<GraphicBuffer> & buf,const Rect & cropRect,uint32_t transform,bool filtering)312*38e8c45fSAndroid Build Coastguard Worker void SurfaceTexture::computeTransformMatrix(float outTransform[16], const sp<GraphicBuffer>& buf,
313*38e8c45fSAndroid Build Coastguard Worker                                             const Rect& cropRect, uint32_t transform,
314*38e8c45fSAndroid Build Coastguard Worker                                             bool filtering) {
315*38e8c45fSAndroid Build Coastguard Worker     // Transform matrices
316*38e8c45fSAndroid Build Coastguard Worker     static const mat4 mtxFlipH(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1);
317*38e8c45fSAndroid Build Coastguard Worker     static const mat4 mtxFlipV(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1);
318*38e8c45fSAndroid Build Coastguard Worker     static const mat4 mtxRot90(0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1);
319*38e8c45fSAndroid Build Coastguard Worker 
320*38e8c45fSAndroid Build Coastguard Worker     mat4 xform;
321*38e8c45fSAndroid Build Coastguard Worker     if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
322*38e8c45fSAndroid Build Coastguard Worker         xform *= mtxFlipH;
323*38e8c45fSAndroid Build Coastguard Worker     }
324*38e8c45fSAndroid Build Coastguard Worker     if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) {
325*38e8c45fSAndroid Build Coastguard Worker         xform *= mtxFlipV;
326*38e8c45fSAndroid Build Coastguard Worker     }
327*38e8c45fSAndroid Build Coastguard Worker     if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
328*38e8c45fSAndroid Build Coastguard Worker         xform *= mtxRot90;
329*38e8c45fSAndroid Build Coastguard Worker     }
330*38e8c45fSAndroid Build Coastguard Worker 
331*38e8c45fSAndroid Build Coastguard Worker     if (!cropRect.isEmpty() && buf.get()) {
332*38e8c45fSAndroid Build Coastguard Worker         float tx = 0.0f, ty = 0.0f, sx = 1.0f, sy = 1.0f;
333*38e8c45fSAndroid Build Coastguard Worker         float bufferWidth = buf->getWidth();
334*38e8c45fSAndroid Build Coastguard Worker         float bufferHeight = buf->getHeight();
335*38e8c45fSAndroid Build Coastguard Worker         float shrinkAmount = 0.0f;
336*38e8c45fSAndroid Build Coastguard Worker         if (filtering) {
337*38e8c45fSAndroid Build Coastguard Worker             // In order to prevent bilinear sampling beyond the edge of the
338*38e8c45fSAndroid Build Coastguard Worker             // crop rectangle we may need to shrink it by 2 texels in each
339*38e8c45fSAndroid Build Coastguard Worker             // dimension.  Normally this would just need to take 1/2 a texel
340*38e8c45fSAndroid Build Coastguard Worker             // off each end, but because the chroma channels of YUV420 images
341*38e8c45fSAndroid Build Coastguard Worker             // are subsampled we may need to shrink the crop region by a whole
342*38e8c45fSAndroid Build Coastguard Worker             // texel on each side.
343*38e8c45fSAndroid Build Coastguard Worker             switch (buf->getPixelFormat()) {
344*38e8c45fSAndroid Build Coastguard Worker                 case PIXEL_FORMAT_RGBA_8888:
345*38e8c45fSAndroid Build Coastguard Worker                 case PIXEL_FORMAT_RGBX_8888:
346*38e8c45fSAndroid Build Coastguard Worker                 case PIXEL_FORMAT_RGBA_FP16:
347*38e8c45fSAndroid Build Coastguard Worker                 case PIXEL_FORMAT_RGBA_1010102:
348*38e8c45fSAndroid Build Coastguard Worker                 case PIXEL_FORMAT_RGB_888:
349*38e8c45fSAndroid Build Coastguard Worker                 case PIXEL_FORMAT_RGB_565:
350*38e8c45fSAndroid Build Coastguard Worker                 case PIXEL_FORMAT_BGRA_8888:
351*38e8c45fSAndroid Build Coastguard Worker                     // We know there's no subsampling of any channels, so we
352*38e8c45fSAndroid Build Coastguard Worker                     // only need to shrink by a half a pixel.
353*38e8c45fSAndroid Build Coastguard Worker                     shrinkAmount = 0.5;
354*38e8c45fSAndroid Build Coastguard Worker                     break;
355*38e8c45fSAndroid Build Coastguard Worker 
356*38e8c45fSAndroid Build Coastguard Worker                 default:
357*38e8c45fSAndroid Build Coastguard Worker                     // If we don't recognize the format, we must assume the
358*38e8c45fSAndroid Build Coastguard Worker                     // worst case (that we care about), which is YUV420.
359*38e8c45fSAndroid Build Coastguard Worker                     shrinkAmount = 1.0;
360*38e8c45fSAndroid Build Coastguard Worker                     break;
361*38e8c45fSAndroid Build Coastguard Worker             }
362*38e8c45fSAndroid Build Coastguard Worker         }
363*38e8c45fSAndroid Build Coastguard Worker 
364*38e8c45fSAndroid Build Coastguard Worker         // Only shrink the dimensions that are not the size of the buffer.
365*38e8c45fSAndroid Build Coastguard Worker         if (cropRect.width() < bufferWidth) {
366*38e8c45fSAndroid Build Coastguard Worker             tx = (float(cropRect.left) + shrinkAmount) / bufferWidth;
367*38e8c45fSAndroid Build Coastguard Worker             sx = (float(cropRect.width()) - (2.0f * shrinkAmount)) / bufferWidth;
368*38e8c45fSAndroid Build Coastguard Worker         }
369*38e8c45fSAndroid Build Coastguard Worker         if (cropRect.height() < bufferHeight) {
370*38e8c45fSAndroid Build Coastguard Worker             ty = (float(bufferHeight - cropRect.bottom) + shrinkAmount) / bufferHeight;
371*38e8c45fSAndroid Build Coastguard Worker             sy = (float(cropRect.height()) - (2.0f * shrinkAmount)) / bufferHeight;
372*38e8c45fSAndroid Build Coastguard Worker         }
373*38e8c45fSAndroid Build Coastguard Worker 
374*38e8c45fSAndroid Build Coastguard Worker         mat4 crop(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, 1, 0, tx, ty, 0, 1);
375*38e8c45fSAndroid Build Coastguard Worker         xform = crop * xform;
376*38e8c45fSAndroid Build Coastguard Worker     }
377*38e8c45fSAndroid Build Coastguard Worker 
378*38e8c45fSAndroid Build Coastguard Worker     // SurfaceFlinger expects the top of its window textures to be at a Y
379*38e8c45fSAndroid Build Coastguard Worker     // coordinate of 0, so SurfaceTexture must behave the same way.  We don't
380*38e8c45fSAndroid Build Coastguard Worker     // want to expose this to applications, however, so we must add an
381*38e8c45fSAndroid Build Coastguard Worker     // additional vertical flip to the transform after all the other transforms.
382*38e8c45fSAndroid Build Coastguard Worker     xform = mtxFlipV * xform;
383*38e8c45fSAndroid Build Coastguard Worker 
384*38e8c45fSAndroid Build Coastguard Worker     memcpy(outTransform, xform.asArray(), sizeof(xform));
385*38e8c45fSAndroid Build Coastguard Worker }
386*38e8c45fSAndroid Build Coastguard Worker 
scaleDownCrop(const Rect & crop,uint32_t bufferWidth,uint32_t bufferHeight)387*38e8c45fSAndroid Build Coastguard Worker Rect SurfaceTexture::scaleDownCrop(const Rect& crop, uint32_t bufferWidth, uint32_t bufferHeight) {
388*38e8c45fSAndroid Build Coastguard Worker     Rect outCrop = crop;
389*38e8c45fSAndroid Build Coastguard Worker 
390*38e8c45fSAndroid Build Coastguard Worker     uint32_t newWidth = static_cast<uint32_t>(crop.width());
391*38e8c45fSAndroid Build Coastguard Worker     uint32_t newHeight = static_cast<uint32_t>(crop.height());
392*38e8c45fSAndroid Build Coastguard Worker 
393*38e8c45fSAndroid Build Coastguard Worker     if (newWidth * bufferHeight > newHeight * bufferWidth) {
394*38e8c45fSAndroid Build Coastguard Worker         newWidth = newHeight * bufferWidth / bufferHeight;
395*38e8c45fSAndroid Build Coastguard Worker         ALOGV("too wide: newWidth = %d", newWidth);
396*38e8c45fSAndroid Build Coastguard Worker     } else if (newWidth * bufferHeight < newHeight * bufferWidth) {
397*38e8c45fSAndroid Build Coastguard Worker         newHeight = newWidth * bufferHeight / bufferWidth;
398*38e8c45fSAndroid Build Coastguard Worker         ALOGV("too tall: newHeight = %d", newHeight);
399*38e8c45fSAndroid Build Coastguard Worker     }
400*38e8c45fSAndroid Build Coastguard Worker 
401*38e8c45fSAndroid Build Coastguard Worker     uint32_t currentWidth = static_cast<uint32_t>(crop.width());
402*38e8c45fSAndroid Build Coastguard Worker     uint32_t currentHeight = static_cast<uint32_t>(crop.height());
403*38e8c45fSAndroid Build Coastguard Worker 
404*38e8c45fSAndroid Build Coastguard Worker     // The crop is too wide
405*38e8c45fSAndroid Build Coastguard Worker     if (newWidth < currentWidth) {
406*38e8c45fSAndroid Build Coastguard Worker         uint32_t dw = currentWidth - newWidth;
407*38e8c45fSAndroid Build Coastguard Worker         auto halfdw = dw / 2;
408*38e8c45fSAndroid Build Coastguard Worker         outCrop.left += halfdw;
409*38e8c45fSAndroid Build Coastguard Worker         // Not halfdw because it would subtract 1 too few when dw is odd
410*38e8c45fSAndroid Build Coastguard Worker         outCrop.right -= (dw - halfdw);
411*38e8c45fSAndroid Build Coastguard Worker         // The crop is too tall
412*38e8c45fSAndroid Build Coastguard Worker     } else if (newHeight < currentHeight) {
413*38e8c45fSAndroid Build Coastguard Worker         uint32_t dh = currentHeight - newHeight;
414*38e8c45fSAndroid Build Coastguard Worker         auto halfdh = dh / 2;
415*38e8c45fSAndroid Build Coastguard Worker         outCrop.top += halfdh;
416*38e8c45fSAndroid Build Coastguard Worker         // Not halfdh because it would subtract 1 too few when dh is odd
417*38e8c45fSAndroid Build Coastguard Worker         outCrop.bottom -= (dh - halfdh);
418*38e8c45fSAndroid Build Coastguard Worker     }
419*38e8c45fSAndroid Build Coastguard Worker 
420*38e8c45fSAndroid Build Coastguard Worker     ALOGV("getCurrentCrop final crop [%d,%d,%d,%d]", outCrop.left, outCrop.top, outCrop.right,
421*38e8c45fSAndroid Build Coastguard Worker           outCrop.bottom);
422*38e8c45fSAndroid Build Coastguard Worker 
423*38e8c45fSAndroid Build Coastguard Worker     return outCrop;
424*38e8c45fSAndroid Build Coastguard Worker }
425*38e8c45fSAndroid Build Coastguard Worker 
getTimestamp()426*38e8c45fSAndroid Build Coastguard Worker nsecs_t SurfaceTexture::getTimestamp() {
427*38e8c45fSAndroid Build Coastguard Worker     SFT_LOGV("getTimestamp");
428*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
429*38e8c45fSAndroid Build Coastguard Worker     return mCurrentTimestamp;
430*38e8c45fSAndroid Build Coastguard Worker }
431*38e8c45fSAndroid Build Coastguard Worker 
getCurrentDataSpace()432*38e8c45fSAndroid Build Coastguard Worker android_dataspace SurfaceTexture::getCurrentDataSpace() {
433*38e8c45fSAndroid Build Coastguard Worker     SFT_LOGV("getCurrentDataSpace");
434*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
435*38e8c45fSAndroid Build Coastguard Worker     return mCurrentDataSpace;
436*38e8c45fSAndroid Build Coastguard Worker }
437*38e8c45fSAndroid Build Coastguard Worker 
getFrameNumber()438*38e8c45fSAndroid Build Coastguard Worker uint64_t SurfaceTexture::getFrameNumber() {
439*38e8c45fSAndroid Build Coastguard Worker     SFT_LOGV("getFrameNumber");
440*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
441*38e8c45fSAndroid Build Coastguard Worker     return mCurrentFrameNumber;
442*38e8c45fSAndroid Build Coastguard Worker }
443*38e8c45fSAndroid Build Coastguard Worker 
getCurrentCrop() const444*38e8c45fSAndroid Build Coastguard Worker Rect SurfaceTexture::getCurrentCrop() const {
445*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
446*38e8c45fSAndroid Build Coastguard Worker     return (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP)
447*38e8c45fSAndroid Build Coastguard Worker             ? scaleDownCrop(mCurrentCrop, mDefaultWidth, mDefaultHeight)
448*38e8c45fSAndroid Build Coastguard Worker             : mCurrentCrop;
449*38e8c45fSAndroid Build Coastguard Worker }
450*38e8c45fSAndroid Build Coastguard Worker 
getCurrentTransform() const451*38e8c45fSAndroid Build Coastguard Worker uint32_t SurfaceTexture::getCurrentTransform() const {
452*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
453*38e8c45fSAndroid Build Coastguard Worker     return mCurrentTransform;
454*38e8c45fSAndroid Build Coastguard Worker }
455*38e8c45fSAndroid Build Coastguard Worker 
getCurrentScalingMode() const456*38e8c45fSAndroid Build Coastguard Worker uint32_t SurfaceTexture::getCurrentScalingMode() const {
457*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
458*38e8c45fSAndroid Build Coastguard Worker     return mCurrentScalingMode;
459*38e8c45fSAndroid Build Coastguard Worker }
460*38e8c45fSAndroid Build Coastguard Worker 
getCurrentFence() const461*38e8c45fSAndroid Build Coastguard Worker sp<Fence> SurfaceTexture::getCurrentFence() const {
462*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
463*38e8c45fSAndroid Build Coastguard Worker     return mCurrentFence;
464*38e8c45fSAndroid Build Coastguard Worker }
465*38e8c45fSAndroid Build Coastguard Worker 
getCurrentFenceTime() const466*38e8c45fSAndroid Build Coastguard Worker std::shared_ptr<FenceTime> SurfaceTexture::getCurrentFenceTime() const {
467*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock lock(mMutex);
468*38e8c45fSAndroid Build Coastguard Worker     return mCurrentFenceTime;
469*38e8c45fSAndroid Build Coastguard Worker }
470*38e8c45fSAndroid Build Coastguard Worker 
freeBufferLocked(int slotIndex)471*38e8c45fSAndroid Build Coastguard Worker void SurfaceTexture::freeBufferLocked(int slotIndex) {
472*38e8c45fSAndroid Build Coastguard Worker     SFT_LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
473*38e8c45fSAndroid Build Coastguard Worker     if (slotIndex == mCurrentTexture) {
474*38e8c45fSAndroid Build Coastguard Worker         mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT;
475*38e8c45fSAndroid Build Coastguard Worker     }
476*38e8c45fSAndroid Build Coastguard Worker     // The slotIndex buffer could have EGL cache, but there is no way to tell
477*38e8c45fSAndroid Build Coastguard Worker     // for sure. Buffers can be freed after SurfaceTexture has detached from GL
478*38e8c45fSAndroid Build Coastguard Worker     // context or View.
479*38e8c45fSAndroid Build Coastguard Worker     mEGLConsumer.onFreeBufferLocked(slotIndex);
480*38e8c45fSAndroid Build Coastguard Worker     ConsumerBase::freeBufferLocked(slotIndex);
481*38e8c45fSAndroid Build Coastguard Worker }
482*38e8c45fSAndroid Build Coastguard Worker 
abandonLocked()483*38e8c45fSAndroid Build Coastguard Worker void SurfaceTexture::abandonLocked() {
484*38e8c45fSAndroid Build Coastguard Worker     SFT_LOGV("abandonLocked");
485*38e8c45fSAndroid Build Coastguard Worker     mEGLConsumer.onAbandonLocked();
486*38e8c45fSAndroid Build Coastguard Worker     ConsumerBase::abandonLocked();
487*38e8c45fSAndroid Build Coastguard Worker }
488*38e8c45fSAndroid Build Coastguard Worker 
setConsumerUsageBits(uint64_t usage)489*38e8c45fSAndroid Build Coastguard Worker status_t SurfaceTexture::setConsumerUsageBits(uint64_t usage) {
490*38e8c45fSAndroid Build Coastguard Worker     return ConsumerBase::setConsumerUsageBits(usage | DEFAULT_USAGE_FLAGS);
491*38e8c45fSAndroid Build Coastguard Worker }
492*38e8c45fSAndroid Build Coastguard Worker 
dumpLocked(String8 & result,const char * prefix) const493*38e8c45fSAndroid Build Coastguard Worker void SurfaceTexture::dumpLocked(String8& result, const char* prefix) const {
494*38e8c45fSAndroid Build Coastguard Worker     result.appendFormat("%smTexName=%d mCurrentTexture=%d\n"
495*38e8c45fSAndroid Build Coastguard Worker                         "%smCurrentCrop=[%d,%d,%d,%d] mCurrentTransform=%#x\n",
496*38e8c45fSAndroid Build Coastguard Worker                         prefix, mTexName, mCurrentTexture, prefix, mCurrentCrop.left,
497*38e8c45fSAndroid Build Coastguard Worker                         mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom,
498*38e8c45fSAndroid Build Coastguard Worker                         mCurrentTransform);
499*38e8c45fSAndroid Build Coastguard Worker 
500*38e8c45fSAndroid Build Coastguard Worker     ConsumerBase::dumpLocked(result, prefix);
501*38e8c45fSAndroid Build Coastguard Worker }
502*38e8c45fSAndroid Build Coastguard Worker 
dequeueBuffer(int * outSlotid,android_dataspace * outDataspace,HdrMetadata * outHdrMetadata,float * outTransformMatrix,uint32_t * outTransform,bool * outQueueEmpty,SurfaceTexture_createReleaseFence createFence,SurfaceTexture_fenceWait fenceWait,void * fencePassThroughHandle,ARect * currentCrop)503*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer> SurfaceTexture::dequeueBuffer(int* outSlotid, android_dataspace* outDataspace,
504*38e8c45fSAndroid Build Coastguard Worker                                                 HdrMetadata* outHdrMetadata,
505*38e8c45fSAndroid Build Coastguard Worker                                                 float* outTransformMatrix, uint32_t* outTransform,
506*38e8c45fSAndroid Build Coastguard Worker                                                 bool* outQueueEmpty,
507*38e8c45fSAndroid Build Coastguard Worker                                                 SurfaceTexture_createReleaseFence createFence,
508*38e8c45fSAndroid Build Coastguard Worker                                                 SurfaceTexture_fenceWait fenceWait,
509*38e8c45fSAndroid Build Coastguard Worker                                                 void* fencePassThroughHandle, ARect* currentCrop) {
510*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock _l(mMutex);
511*38e8c45fSAndroid Build Coastguard Worker     sp<GraphicBuffer> buffer;
512*38e8c45fSAndroid Build Coastguard Worker 
513*38e8c45fSAndroid Build Coastguard Worker     if (mAbandoned) {
514*38e8c45fSAndroid Build Coastguard Worker         SFT_LOGE("dequeueImage: SurfaceTexture is abandoned!");
515*38e8c45fSAndroid Build Coastguard Worker         return buffer;
516*38e8c45fSAndroid Build Coastguard Worker     }
517*38e8c45fSAndroid Build Coastguard Worker 
518*38e8c45fSAndroid Build Coastguard Worker     if (mOpMode != OpMode::attachedToConsumer) {
519*38e8c45fSAndroid Build Coastguard Worker         SFT_LOGE("dequeueImage: SurfaceTexture is not attached to a View");
520*38e8c45fSAndroid Build Coastguard Worker         return buffer;
521*38e8c45fSAndroid Build Coastguard Worker     }
522*38e8c45fSAndroid Build Coastguard Worker 
523*38e8c45fSAndroid Build Coastguard Worker     buffer = mImageConsumer.dequeueBuffer(outSlotid, outDataspace, outHdrMetadata, outQueueEmpty,
524*38e8c45fSAndroid Build Coastguard Worker                                           *this, createFence, fenceWait, fencePassThroughHandle);
525*38e8c45fSAndroid Build Coastguard Worker     memcpy(outTransformMatrix, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix));
526*38e8c45fSAndroid Build Coastguard Worker     *outTransform = mCurrentTransform;
527*38e8c45fSAndroid Build Coastguard Worker     *currentCrop = mCurrentCrop;
528*38e8c45fSAndroid Build Coastguard Worker     return buffer;
529*38e8c45fSAndroid Build Coastguard Worker }
530*38e8c45fSAndroid Build Coastguard Worker 
setSurfaceTextureListener(const sp<android::SurfaceTexture::SurfaceTextureListener> & listener)531*38e8c45fSAndroid Build Coastguard Worker void SurfaceTexture::setSurfaceTextureListener(
532*38e8c45fSAndroid Build Coastguard Worker         const sp<android::SurfaceTexture::SurfaceTextureListener>& listener) {
533*38e8c45fSAndroid Build Coastguard Worker     SFT_LOGV("setSurfaceTextureListener");
534*38e8c45fSAndroid Build Coastguard Worker 
535*38e8c45fSAndroid Build Coastguard Worker     Mutex::Autolock _l(mMutex);
536*38e8c45fSAndroid Build Coastguard Worker     mSurfaceTextureListener = listener;
537*38e8c45fSAndroid Build Coastguard Worker     if (mSurfaceTextureListener != nullptr) {
538*38e8c45fSAndroid Build Coastguard Worker         mFrameAvailableListenerProxy =
539*38e8c45fSAndroid Build Coastguard Worker                 sp<FrameAvailableListenerProxy>::make(mSurfaceTextureListener);
540*38e8c45fSAndroid Build Coastguard Worker         setFrameAvailableListener(mFrameAvailableListenerProxy);
541*38e8c45fSAndroid Build Coastguard Worker     } else {
542*38e8c45fSAndroid Build Coastguard Worker         mFrameAvailableListenerProxy.clear();
543*38e8c45fSAndroid Build Coastguard Worker     }
544*38e8c45fSAndroid Build Coastguard Worker }
545*38e8c45fSAndroid Build Coastguard Worker 
onFrameAvailable(const BufferItem & item)546*38e8c45fSAndroid Build Coastguard Worker void SurfaceTexture::FrameAvailableListenerProxy::onFrameAvailable(const BufferItem& item) {
547*38e8c45fSAndroid Build Coastguard Worker     const auto listener = mSurfaceTextureListener.promote();
548*38e8c45fSAndroid Build Coastguard Worker     if (listener) {
549*38e8c45fSAndroid Build Coastguard Worker         listener->onFrameAvailable(item);
550*38e8c45fSAndroid Build Coastguard Worker     }
551*38e8c45fSAndroid Build Coastguard Worker }
552*38e8c45fSAndroid Build Coastguard Worker 
553*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_SETFRAMERATE)
onSetFrameRate(float frameRate,int8_t compatibility,int8_t changeFrameRateStrategy)554*38e8c45fSAndroid Build Coastguard Worker void SurfaceTexture::onSetFrameRate(float frameRate, int8_t compatibility,
555*38e8c45fSAndroid Build Coastguard Worker                                     int8_t changeFrameRateStrategy) {
556*38e8c45fSAndroid Build Coastguard Worker     SFT_LOGV("onSetFrameRate: %.2f", frameRate);
557*38e8c45fSAndroid Build Coastguard Worker 
558*38e8c45fSAndroid Build Coastguard Worker     auto listener = [&] {
559*38e8c45fSAndroid Build Coastguard Worker         Mutex::Autolock _l(mMutex);
560*38e8c45fSAndroid Build Coastguard Worker         return mSurfaceTextureListener;
561*38e8c45fSAndroid Build Coastguard Worker     }();
562*38e8c45fSAndroid Build Coastguard Worker 
563*38e8c45fSAndroid Build Coastguard Worker     if (listener) {
564*38e8c45fSAndroid Build Coastguard Worker         listener->onSetFrameRate(frameRate, compatibility, changeFrameRateStrategy);
565*38e8c45fSAndroid Build Coastguard Worker     }
566*38e8c45fSAndroid Build Coastguard Worker }
567*38e8c45fSAndroid Build Coastguard Worker #endif
568*38e8c45fSAndroid Build Coastguard Worker 
initialize()569*38e8c45fSAndroid Build Coastguard Worker void SurfaceTexture::initialize() {
570*38e8c45fSAndroid Build Coastguard Worker     SFT_LOGV("SurfaceTexture");
571*38e8c45fSAndroid Build Coastguard Worker 
572*38e8c45fSAndroid Build Coastguard Worker     memcpy(mCurrentTransformMatrix, mtxIdentity.asArray(), sizeof(mCurrentTransformMatrix));
573*38e8c45fSAndroid Build Coastguard Worker 
574*38e8c45fSAndroid Build Coastguard Worker     mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);
575*38e8c45fSAndroid Build Coastguard Worker }
576*38e8c45fSAndroid Build Coastguard Worker 
577*38e8c45fSAndroid Build Coastguard Worker } // namespace android
578