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