168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis/*
268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * Copyright (C) 2010 The Android Open Source Project
368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis *
468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * Licensed under the Apache License, Version 2.0 (the "License");
568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * you may not use this file except in compliance with the License.
668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * You may obtain a copy of the License at
768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis *
868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis *      http://www.apache.org/licenses/LICENSE-2.0
968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis *
1068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * Unless required by applicable law or agreed to in writing, software
1168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * distributed under the License is distributed on an "AS IS" BASIS,
1268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * See the License for the specific language governing permissions and
1468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * limitations under the License.
1568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis */
1668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
1768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#define LOG_TAG "SurfaceTexture"
187dc00d5eb27de41f93a7e232b3cd374c84eb77d1Jamie Gennis//#define LOG_NDEBUG 0
1968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
2068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#define GL_GLEXT_PROTOTYPES
2168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#define EGL_EGLEXT_PROTOTYPES
2268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
2368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#include <EGL/egl.h>
2468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#include <EGL/eglext.h>
2568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#include <GLES2/gl2.h>
2668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#include <GLES2/gl2ext.h>
2768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
2868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#include <gui/SurfaceTexture.h>
2968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
3027cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian#include <hardware/hardware.h>
3127cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian
3268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#include <surfaceflinger/ISurfaceComposer.h>
3368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#include <surfaceflinger/SurfaceComposerClient.h>
34f7acf162f8d682c6ebc9af41ca76795b79509193Jamie Gennis#include <surfaceflinger/IGraphicBufferAlloc.h>
3568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
3668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#include <utils/Log.h>
377f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian#include <utils/String8.h>
3868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
3977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis// This compile option causes SurfaceTexture to return the buffer that is currently
4077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis// attached to the GL texture from dequeueBuffer when no other buffers are
4177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis// available.  It requires the drivers (Gralloc, GL, OMX IL, and Camera) to do
4277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis// implicit cross-process synchronization to prevent the buffer from being
4377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis// written to before the buffer has (a) been detached from the GL texture and
4477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis// (b) all GL reads from the buffer have completed.
45e2fa30cba0c3412d07214dec346bb21a562d3461Mathias Agopian#ifdef ALLOW_DEQUEUE_CURRENT_BUFFER
46e2fa30cba0c3412d07214dec346bb21a562d3461Mathias Agopian#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER    true
47e2fa30cba0c3412d07214dec346bb21a562d3461Mathias Agopian#warning "ALLOW_DEQUEUE_CURRENT_BUFFER enabled"
48e2fa30cba0c3412d07214dec346bb21a562d3461Mathias Agopian#else
49e2fa30cba0c3412d07214dec346bb21a562d3461Mathias Agopian#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER    false
50e2fa30cba0c3412d07214dec346bb21a562d3461Mathias Agopian#endif
518618ebcc5d20a5983da1fc6200d50c3662aca6e3Mathias Agopian
5277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis// This compile option makes SurfaceTexture use the EGL_KHR_fence_sync extension
5377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis// to synchronize access to the buffers.  It will cause dequeueBuffer to stall,
5477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis// waiting for the GL reads for the buffer being dequeued to complete before
5577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis// allowing the buffer to be dequeued.
5677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis#ifdef USE_FENCE_SYNC
5777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis#ifdef ALLOW_DEQUEUE_CURRENT_BUFFER
5877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis#error "USE_FENCE_SYNC and ALLOW_DEQUEUE_CURRENT_BUFFER are incompatible"
5977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis#endif
6077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis#endif
6177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis
6244a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis// Macros for including the SurfaceTexture name in log messages
6344a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis#define ST_LOGV(x, ...) LOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
6444a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis#define ST_LOGD(x, ...) LOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
6544a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis#define ST_LOGI(x, ...) LOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
6644a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis#define ST_LOGW(x, ...) LOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
6744a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis#define ST_LOGE(x, ...) LOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
688618ebcc5d20a5983da1fc6200d50c3662aca6e3Mathias Agopian
6968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennisnamespace android {
7068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
71b598fb90727be45e926a11abefc319819a733540Jamie Gennis// Transform matrices
72b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatic float mtxIdentity[16] = {
73b598fb90727be45e926a11abefc319819a733540Jamie Gennis    1, 0, 0, 0,
74b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 1, 0, 0,
75b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 0, 1, 0,
76b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 0, 0, 1,
77b598fb90727be45e926a11abefc319819a733540Jamie Gennis};
78b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatic float mtxFlipH[16] = {
79b598fb90727be45e926a11abefc319819a733540Jamie Gennis    -1, 0, 0, 0,
80b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 1, 0, 0,
81b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 0, 1, 0,
82b598fb90727be45e926a11abefc319819a733540Jamie Gennis    1, 0, 0, 1,
83b598fb90727be45e926a11abefc319819a733540Jamie Gennis};
84b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatic float mtxFlipV[16] = {
85b598fb90727be45e926a11abefc319819a733540Jamie Gennis    1, 0, 0, 0,
86b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, -1, 0, 0,
87b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 0, 1, 0,
88b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 1, 0, 1,
89b598fb90727be45e926a11abefc319819a733540Jamie Gennis};
90b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatic float mtxRot90[16] = {
91b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 1, 0, 0,
92b598fb90727be45e926a11abefc319819a733540Jamie Gennis    -1, 0, 0, 0,
93b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 0, 1, 0,
94b598fb90727be45e926a11abefc319819a733540Jamie Gennis    1, 0, 0, 1,
95b598fb90727be45e926a11abefc319819a733540Jamie Gennis};
96b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatic float mtxRot180[16] = {
97b598fb90727be45e926a11abefc319819a733540Jamie Gennis    -1, 0, 0, 0,
98b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, -1, 0, 0,
99b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 0, 1, 0,
100b598fb90727be45e926a11abefc319819a733540Jamie Gennis    1, 1, 0, 1,
101b598fb90727be45e926a11abefc319819a733540Jamie Gennis};
102b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatic float mtxRot270[16] = {
103b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, -1, 0, 0,
104b598fb90727be45e926a11abefc319819a733540Jamie Gennis    1, 0, 0, 0,
105b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 0, 1, 0,
106b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 1, 0, 1,
107b598fb90727be45e926a11abefc319819a733540Jamie Gennis};
108b598fb90727be45e926a11abefc319819a733540Jamie Gennis
109b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]);
110b598fb90727be45e926a11abefc319819a733540Jamie Gennis
11144a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis// Get an ID that's unique within this process.
11244a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennisstatic int32_t createProcessUniqueId() {
11344a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis    static volatile int32_t globalCounter = 0;
11444a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis    return android_atomic_inc(&globalCounter);
11544a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis}
11644a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis
1178606fefa219d63d0a0f3df1b9dcf49cfbfa5b3e5Jamie GennisSurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
11877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        GLenum texTarget, bool useFenceSync) :
119e5a1bffd9106b1d82259de1a202e1f2f28742392Mathias Agopian    mDefaultWidth(1),
120e5a1bffd9106b1d82259de1a202e1f2f28742392Mathias Agopian    mDefaultHeight(1),
121e5a1bffd9106b1d82259de1a202e1f2f28742392Mathias Agopian    mPixelFormat(PIXEL_FORMAT_RGBA_8888),
122402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    mBufferCount(MIN_ASYNC_BUFFER_SLOTS),
123402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    mClientBufferCount(0),
124402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS),
125c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala    mCurrentTexture(INVALID_BUFFER_SLOT),
126c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala    mCurrentTransform(0),
127c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala    mCurrentTimestamp(0),
128c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala    mNextTransform(0),
12909d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian    mNextScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
1305bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian    mTexName(tex),
1310904d0af81e8a0a5404d6c03f4dcea02bea8170dGrace Kloba    mSynchronousMode(false),
1329709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis    mAllowSynchronousMode(allowSynchronousMode),
1335ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    mConnectedApi(NO_CONNECTED_API),
1348606fefa219d63d0a0f3df1b9dcf49cfbfa5b3e5Jamie Gennis    mAbandoned(false),
13577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis#ifdef USE_FENCE_SYNC
13677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis    mUseFenceSync(useFenceSync),
13777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis#else
13877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis    mUseFenceSync(false),
13977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis#endif
140f1e868f68204bf469a0c162b84af0e651d513ac8Sunita Nadampalli    mTexTarget(texTarget),
141f1e868f68204bf469a0c162b84af0e651d513ac8Sunita Nadampalli    mFrameCounter(0) {
14244a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis    // Choose a name using the PID and a process-unique ID.
14344a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis    mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
14444a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis
145e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("SurfaceTexture");
146f7acf162f8d682c6ebc9af41ca76795b79509193Jamie Gennis    sp<ISurfaceComposer> composer(ComposerService::getComposerService());
147f7acf162f8d682c6ebc9af41ca76795b79509193Jamie Gennis    mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
148926340cf56c9a2d21008d050a4e0f1390cf648bfMathias Agopian    mNextCrop.makeInvalid();
14944a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis    memcpy(mCurrentTransformMatrix, mtxIdentity,
15044a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis            sizeof(mCurrentTransformMatrix));
15168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
15268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
15368e4a7ac849b681b1fb769857fc04f64262480c4Jamie GennisSurfaceTexture::~SurfaceTexture() {
154e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("~SurfaceTexture");
155a04cda9986366ab480ad8008c4d923271b05d78eMathias Agopian    freeAllBuffersLocked();
15668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
15768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
158402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopianstatus_t SurfaceTexture::setBufferCountServerLocked(int bufferCount) {
159402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    if (bufferCount > NUM_BUFFER_SLOTS)
160402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        return BAD_VALUE;
161402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian
162402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    // special-case, nothing to do
163402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    if (bufferCount == mBufferCount)
164402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        return OK;
165402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian
166402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    if (!mClientBufferCount &&
167402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        bufferCount >= mBufferCount) {
168402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        // easy, we just have more buffers
169402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        mBufferCount = bufferCount;
170402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        mServerBufferCount = bufferCount;
171402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        mDequeueCondition.signal();
172402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    } else {
173402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        // we're here because we're either
174402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        // - reducing the number of available buffers
175402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        // - or there is a client-buffer-count in effect
176402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian
177402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        // less than 2 buffers is never allowed
178402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        if (bufferCount < 2)
179402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian            return BAD_VALUE;
180402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian
181402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        // when there is non client-buffer-count in effect, the client is not
182402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        // allowed to dequeue more than one buffer at a time,
183402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        // so the next time they dequeue a buffer, we know that they don't
184402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        // own one. the actual resizing will happen during the next
185402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        // dequeueBuffer.
186402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian
187402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        mServerBufferCount = bufferCount;
188402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    }
189402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    return OK;
190402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian}
191402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian
192402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopianstatus_t SurfaceTexture::setBufferCountServer(int bufferCount) {
193402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    Mutex::Autolock lock(mMutex);
194402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    return setBufferCountServerLocked(bufferCount);
195402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian}
196402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian
19768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennisstatus_t SurfaceTexture::setBufferCount(int bufferCount) {
198e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("setBufferCount: count=%d", bufferCount);
1995bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian    Mutex::Autolock lock(mMutex);
20096dcc978430f0daf6d73fee96a01779ed537a0ceJamie Gennis
2015ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    if (mAbandoned) {
20244a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis        ST_LOGE("setBufferCount: SurfaceTexture has been abandoned!");
2035ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis        return NO_INIT;
2045ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    }
205c9ec69eb6f07881e1d0582156e5697eff69f5546Pannag Sanketi    if (bufferCount > NUM_BUFFER_SLOTS) {
20644a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis        ST_LOGE("setBufferCount: bufferCount larger than slots available");
207c9ec69eb6f07881e1d0582156e5697eff69f5546Pannag Sanketi        return BAD_VALUE;
208c9ec69eb6f07881e1d0582156e5697eff69f5546Pannag Sanketi    }
209c9ec69eb6f07881e1d0582156e5697eff69f5546Pannag Sanketi
210402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    // Error out if the user has dequeued buffers
211402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    for (int i=0 ; i<mBufferCount ; i++) {
212402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) {
21344a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis            ST_LOGE("setBufferCount: client owns some buffers");
214402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian            return -EINVAL;
215402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        }
216402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    }
2175bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian
218d995b08353a7e912fee6397710262bee7671ad38Jamie Gennis    const int minBufferSlots = mSynchronousMode ?
219d995b08353a7e912fee6397710262bee7671ad38Jamie Gennis            MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
220402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    if (bufferCount == 0) {
221402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        mClientBufferCount = 0;
222402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        bufferCount = (mServerBufferCount >= minBufferSlots) ?
223402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian                mServerBufferCount : minBufferSlots;
224402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        return setBufferCountServerLocked(bufferCount);
225402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    }
226402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian
227d995b08353a7e912fee6397710262bee7671ad38Jamie Gennis    if (bufferCount < minBufferSlots) {
22844a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis        ST_LOGE("setBufferCount: requested buffer count (%d) is less than "
229d995b08353a7e912fee6397710262bee7671ad38Jamie Gennis                "minimum (%d)", bufferCount, minBufferSlots);
23096dcc978430f0daf6d73fee96a01779ed537a0ceJamie Gennis        return BAD_VALUE;
23196dcc978430f0daf6d73fee96a01779ed537a0ceJamie Gennis    }
23296dcc978430f0daf6d73fee96a01779ed537a0ceJamie Gennis
233402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    // here we're guaranteed that the client doesn't have dequeued buffers
234402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    // and will release all of its buffer references.
235a04cda9986366ab480ad8008c4d923271b05d78eMathias Agopian    freeAllBuffersLocked();
23668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    mBufferCount = bufferCount;
237402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    mClientBufferCount = bufferCount;
238d369dc42506ec003f1839bb9e27edada411324b5Jamie Gennis    mCurrentTexture = INVALID_BUFFER_SLOT;
2395bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian    mQueue.clear();
2405bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian    mDequeueCondition.signal();
24168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    return OK;
24268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
24368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
244e5a1bffd9106b1d82259de1a202e1f2f28742392Mathias Agopianstatus_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h)
245e5a1bffd9106b1d82259de1a202e1f2f28742392Mathias Agopian{
246e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h);
247f3503c2c30dc0b7eb7603998469f437136497c5cMathias Agopian    if (!w || !h) {
24844a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis        ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)",
24944a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis                w, h);
250f3503c2c30dc0b7eb7603998469f437136497c5cMathias Agopian        return BAD_VALUE;
251e5a1bffd9106b1d82259de1a202e1f2f28742392Mathias Agopian    }
252f3503c2c30dc0b7eb7603998469f437136497c5cMathias Agopian
253f3503c2c30dc0b7eb7603998469f437136497c5cMathias Agopian    Mutex::Autolock lock(mMutex);
254f3503c2c30dc0b7eb7603998469f437136497c5cMathias Agopian    mDefaultWidth = w;
255f3503c2c30dc0b7eb7603998469f437136497c5cMathias Agopian    mDefaultHeight = h;
256e5a1bffd9106b1d82259de1a202e1f2f28742392Mathias Agopian    return OK;
257e5a1bffd9106b1d82259de1a202e1f2f28742392Mathias Agopian}
258e5a1bffd9106b1d82259de1a202e1f2f28742392Mathias Agopian
2595ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennisstatus_t SurfaceTexture::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
260e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("requestBuffer: slot=%d", slot);
26168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    Mutex::Autolock lock(mMutex);
2625ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    if (mAbandoned) {
26344a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis        ST_LOGE("requestBuffer: SurfaceTexture has been abandoned!");
2645ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis        return NO_INIT;
2655ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    }
2665ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    if (slot < 0 || mBufferCount <= slot) {
26744a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis        ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d",
2685ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis                mBufferCount, slot);
2695ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis        return BAD_VALUE;
27068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    }
2715ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    mSlots[slot].mRequestBufferCalled = true;
2725ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    *buf = mSlots[slot].mGraphicBuffer;
2735ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    return NO_ERROR;
2740297dcae8fddb18ab9e28ba1858a57a8aec3ef32Mathias Agopian}
2750297dcae8fddb18ab9e28ba1858a57a8aec3ef32Mathias Agopian
2760297dcae8fddb18ab9e28ba1858a57a8aec3ef32Mathias Agopianstatus_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
2770297dcae8fddb18ab9e28ba1858a57a8aec3ef32Mathias Agopian        uint32_t format, uint32_t usage) {
278e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage);
2790297dcae8fddb18ab9e28ba1858a57a8aec3ef32Mathias Agopian
280c9ec69eb6f07881e1d0582156e5697eff69f5546Pannag Sanketi    if ((w && !h) || (!w && h)) {
28144a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis        ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);
2820297dcae8fddb18ab9e28ba1858a57a8aec3ef32Mathias Agopian        return BAD_VALUE;
2830297dcae8fddb18ab9e28ba1858a57a8aec3ef32Mathias Agopian    }
2840297dcae8fddb18ab9e28ba1858a57a8aec3ef32Mathias Agopian
285402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    status_t returnFlags(OK);
28677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis    EGLDisplay dpy = EGL_NO_DISPLAY;
28777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis    EGLSyncKHR fence = EGL_NO_SYNC_KHR;
288402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian
28977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis    { // Scope for the lock
29077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        Mutex::Autolock lock(mMutex);
291402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian
29277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        int found = -1;
29377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        int foundSync = -1;
29477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        int dequeuedCount = 0;
29577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        bool tryAgain = true;
29677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        while (tryAgain) {
29777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            if (mAbandoned) {
29877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
29977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                return NO_INIT;
30077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            }
301402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian
30277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // We need to wait for the FIFO to drain if the number of buffer
30377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // needs to change.
30477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            //
30577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // The condition "number of buffers needs to change" is true if
30677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // - the client doesn't care about how many buffers there are
30777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // - AND the actual number of buffer is different from what was
30877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            //   set in the last setBufferCountServer()
30977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            //                         - OR -
31077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            //   setBufferCountServer() was set to a value incompatible with
31177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            //   the synchronization mode (for instance because the sync mode
31277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            //   changed since)
31377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            //
31477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // As long as this condition is true AND the FIFO is not empty, we
31577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // wait on mDequeueCondition.
31677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis
31777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            const int minBufferCountNeeded = mSynchronousMode ?
31877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                    MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
31977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis
32077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            const bool numberOfBuffersNeedsToChange = !mClientBufferCount &&
32177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                    ((mServerBufferCount != mBufferCount) ||
32277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                            (mServerBufferCount < minBufferCountNeeded));
32377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis
32477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            if (!mQueue.isEmpty() && numberOfBuffersNeedsToChange) {
32577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                // wait for the FIFO to drain
32677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                mDequeueCondition.wait(mMutex);
32777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                // NOTE: we continue here because we need to reevaluate our
32877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                // whole state (eg: we could be abandoned or disconnected)
32977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                continue;
3305bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian            }
3318618ebcc5d20a5983da1fc6200d50c3662aca6e3Mathias Agopian
33277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            if (numberOfBuffersNeedsToChange) {
33377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                // here we're guaranteed that mQueue is empty
33477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                freeAllBuffersLocked();
33577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                mBufferCount = mServerBufferCount;
33677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                if (mBufferCount < minBufferCountNeeded)
33777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                    mBufferCount = minBufferCountNeeded;
33877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                mCurrentTexture = INVALID_BUFFER_SLOT;
33977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
34077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            }
3418618ebcc5d20a5983da1fc6200d50c3662aca6e3Mathias Agopian
34277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // look for a free buffer to give to the client
34377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            found = INVALID_BUFFER_SLOT;
34477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            foundSync = INVALID_BUFFER_SLOT;
34577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            dequeuedCount = 0;
34677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            for (int i = 0; i < mBufferCount; i++) {
34777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                const int state = mSlots[i].mBufferState;
34877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                if (state == BufferSlot::DEQUEUED) {
34977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                    dequeuedCount++;
3508618ebcc5d20a5983da1fc6200d50c3662aca6e3Mathias Agopian                }
35177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis
35277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                // if buffer is FREE it CANNOT be current
35377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                LOGW_IF((state == BufferSlot::FREE) && (mCurrentTexture==i),
35477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                        "dequeueBuffer: buffer %d is both FREE and current!",
35577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                        i);
35677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis
35777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER) {
35877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                    if (state == BufferSlot::FREE || i == mCurrentTexture) {
359f1e868f68204bf469a0c162b84af0e651d513ac8Sunita Nadampalli                        foundSync = i;
36077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                        if (i != mCurrentTexture) {
36177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                            found = i;
36277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                            break;
36377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                        }
36477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                    }
36577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                } else {
36677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                    if (state == BufferSlot::FREE) {
36777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                        /* We return the oldest of the free buffers to avoid
36877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                         * stalling the producer if possible.  This is because
36977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                         * the consumer may still have pending reads of the
37077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                         * buffers in flight.
37177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                         */
37277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                        bool isOlder = mSlots[i].mFrameNumber <
37377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                                mSlots[found].mFrameNumber;
37477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                        if (found < 0 || isOlder) {
37577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                            foundSync = i;
37677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                            found = i;
37777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                        }
378f1e868f68204bf469a0c162b84af0e651d513ac8Sunita Nadampalli                    }
3795bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian                }
3805bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian            }
381402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian
38277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // clients are not allowed to dequeue more than one buffer
38377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // if they didn't set a buffer count.
38477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            if (!mClientBufferCount && dequeuedCount) {
38577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without "
38677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                        "setting the buffer count");
38777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                return -EINVAL;
38877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            }
389402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian
39077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // See whether a buffer has been queued since the last
39177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // setBufferCount so we know whether to perform the
39277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // MIN_UNDEQUEUED_BUFFERS check below.
39377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            bool bufferHasBeenQueued = mCurrentTexture != INVALID_BUFFER_SLOT;
39477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            if (bufferHasBeenQueued) {
39577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                // make sure the client is not trying to dequeue more buffers
39677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                // than allowed.
39777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                const int avail = mBufferCount - (dequeuedCount+1);
39877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                if (avail < (MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode))) {
39977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                    ST_LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded "
40077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                            "(dequeued=%d)",
40177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                            MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode),
40277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                            dequeuedCount);
40377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                    return -EBUSY;
40477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                }
40577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            }
40677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis
40777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // we're in synchronous mode and didn't find a buffer, we need to
40877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // wait for some buffers to be consumed
40977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            tryAgain = mSynchronousMode && (foundSync == INVALID_BUFFER_SLOT);
41077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            if (tryAgain) {
41177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                mDequeueCondition.wait(mMutex);
41244e9e0d825aef362a3413dfd63812962f5de1b1aJamie Gennis            }
413402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        }
414402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian
41577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        if (mSynchronousMode && found == INVALID_BUFFER_SLOT) {
41677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // foundSync guaranteed to be != INVALID_BUFFER_SLOT
41777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            found = foundSync;
4180297dcae8fddb18ab9e28ba1858a57a8aec3ef32Mathias Agopian        }
4195bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian
42077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        if (found == INVALID_BUFFER_SLOT) {
42177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // This should not happen.
42277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            ST_LOGE("dequeueBuffer: no available buffer slots");
42377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            return -EBUSY;
42477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        }
4255bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian
42677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        const int buf = found;
42777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        *outBuf = found;
4280297dcae8fddb18ab9e28ba1858a57a8aec3ef32Mathias Agopian
42977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        const bool useDefaultSize = !w && !h;
43077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        if (useDefaultSize) {
43177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // use the default size
43277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            w = mDefaultWidth;
43377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            h = mDefaultHeight;
43477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        }
435e5a1bffd9106b1d82259de1a202e1f2f28742392Mathias Agopian
43677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        const bool updateFormat = (format != 0);
43777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        if (!updateFormat) {
43877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            // keep the current (or default) format
43977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            format = mPixelFormat;
44077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        }
441e5a1bffd9106b1d82259de1a202e1f2f28742392Mathias Agopian
44277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        // buffer is now in DEQUEUED (but can also be current at the same time,
44377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        // if we're in synchronous mode)
44477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
44577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis
44677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
44777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        if ((buffer == NULL) ||
44877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            (uint32_t(buffer->width)  != w) ||
44977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            (uint32_t(buffer->height) != h) ||
45077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            (uint32_t(buffer->format) != format) ||
45177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            ((uint32_t(buffer->usage) & usage) != usage))
45277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        {
45377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            usage |= GraphicBuffer::USAGE_HW_TEXTURE;
45477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            status_t error;
45577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            sp<GraphicBuffer> graphicBuffer(
45677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                    mGraphicBufferAlloc->createGraphicBuffer(
45777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                            w, h, format, usage, &error));
45877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            if (graphicBuffer == 0) {
45977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer "
46077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                        "failed");
46177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                return error;
46277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            }
46377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            if (updateFormat) {
46477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                mPixelFormat = format;
46577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            }
46677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            mSlots[buf].mGraphicBuffer = graphicBuffer;
46777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            mSlots[buf].mRequestBufferCalled = false;
46877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            mSlots[buf].mFence = EGL_NO_SYNC_KHR;
46977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            if (mSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) {
47077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                eglDestroyImageKHR(mSlots[buf].mEglDisplay,
47177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                        mSlots[buf].mEglImage);
47277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                mSlots[buf].mEglImage = EGL_NO_IMAGE_KHR;
47377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
47477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            }
47577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            if (mCurrentTexture == buf) {
47677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                // The current texture no longer references the buffer in this slot
47777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                // since we just allocated a new buffer.
47877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                mCurrentTexture = INVALID_BUFFER_SLOT;
47977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            }
48077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
48177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        }
48277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis
48377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        dpy = mSlots[buf].mEglDisplay;
48477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        fence = mSlots[buf].mFence;
48577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        mSlots[buf].mFence = EGL_NO_SYNC_KHR;
486e5a1bffd9106b1d82259de1a202e1f2f28742392Mathias Agopian    }
487e5a1bffd9106b1d82259de1a202e1f2f28742392Mathias Agopian
48877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis    if (fence != EGL_NO_SYNC_KHR) {
48977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000);
49077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        // If something goes wrong, log the error, but return the buffer without
49177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        // synchronizing access to it.  It's too late at this point to abort the
49277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        // dequeue operation.
49377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        if (result == EGL_FALSE) {
49477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            LOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError());
49577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
49677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            LOGE("dequeueBuffer: timeout waiting for fence");
49768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        }
49877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        eglDestroySyncKHR(dpy, fence);
499e5a1bffd9106b1d82259de1a202e1f2f28742392Mathias Agopian    }
50077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis
501798b9cdf8ca6fdede46c7f697bed78756f9029f9Jamie Gennis    ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf,
502798b9cdf8ca6fdede46c7f697bed78756f9029f9Jamie Gennis            mSlots[*outBuf].mGraphicBuffer->handle, returnFlags);
50377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis
504402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    return returnFlags;
50568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
50668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
5075bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopianstatus_t SurfaceTexture::setSynchronousMode(bool enabled) {
508e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("setSynchronousMode: enabled=%d", enabled);
5095bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian    Mutex::Autolock lock(mMutex);
510402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian
5115ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    if (mAbandoned) {
51244a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis        ST_LOGE("setSynchronousMode: SurfaceTexture has been abandoned!");
5135ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis        return NO_INIT;
5145ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    }
5155ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis
516402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    status_t err = OK;
5170904d0af81e8a0a5404d6c03f4dcea02bea8170dGrace Kloba    if (!mAllowSynchronousMode && enabled)
5180904d0af81e8a0a5404d6c03f4dcea02bea8170dGrace Kloba        return err;
5190904d0af81e8a0a5404d6c03f4dcea02bea8170dGrace Kloba
520402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    if (!enabled) {
521402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        // going to asynchronous mode, drain the queue
5225c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian        err = drainQueueLocked();
5235c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian        if (err != NO_ERROR)
5245c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian            return err;
525402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    }
526402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian
5275bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian    if (mSynchronousMode != enabled) {
528402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        // - if we're going to asynchronous mode, the queue is guaranteed to be
529402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        // empty here
530402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        // - if the client set the number of buffers, we're guaranteed that
531402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian        // we have at least 3 (because we don't allow less)
5325bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian        mSynchronousMode = enabled;
5335bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian        mDequeueCondition.signal();
5345bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian    }
535402ff24aa199a2587498b694e2be67ceb1265c69Mathias Agopian    return err;
5365bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian}
5375bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian
538f07b8a3f691be39083fb5163f9456bcfa566f93fMathias Agopianstatus_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp,
539f07b8a3f691be39083fb5163f9456bcfa566f93fMathias Agopian        uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
540e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("queueBuffer: slot=%d time=%lld", buf, timestamp);
541e845c352c8eb93412fa7caedb5435d3597c795d0Mathias Agopian
542e845c352c8eb93412fa7caedb5435d3597c795d0Mathias Agopian    sp<FrameAvailableListener> listener;
543e845c352c8eb93412fa7caedb5435d3597c795d0Mathias Agopian
544e845c352c8eb93412fa7caedb5435d3597c795d0Mathias Agopian    { // scope for the lock
545a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis        Mutex::Autolock lock(mMutex);
5465ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis        if (mAbandoned) {
54744a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis            ST_LOGE("queueBuffer: SurfaceTexture has been abandoned!");
5485ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis            return NO_INIT;
5495ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis        }
550a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis        if (buf < 0 || buf >= mBufferCount) {
55144a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis            ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d",
552a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis                    mBufferCount, buf);
553a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis            return -EINVAL;
554a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis        } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
55544a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis            ST_LOGE("queueBuffer: slot %d is not owned by the client "
55644a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis                    "(state=%d)", buf, mSlots[buf].mBufferState);
557a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis            return -EINVAL;
558a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis        } else if (buf == mCurrentTexture) {
55944a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis            ST_LOGE("queueBuffer: slot %d is current!", buf);
560a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis            return -EINVAL;
561a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis        } else if (!mSlots[buf].mRequestBufferCalled) {
56244a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis            ST_LOGE("queueBuffer: slot %d was enqueued without requesting a "
563a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis                    "buffer", buf);
564a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis            return -EINVAL;
565a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis        }
566e845c352c8eb93412fa7caedb5435d3597c795d0Mathias Agopian
567a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis        if (mSynchronousMode) {
568bd5404d0312752e7c8946e8540129f0d2d97bcd7Jamie Gennis            // In synchronous mode we queue all buffers in a FIFO.
5695bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian            mQueue.push_back(buf);
570bd5404d0312752e7c8946e8540129f0d2d97bcd7Jamie Gennis
571bd5404d0312752e7c8946e8540129f0d2d97bcd7Jamie Gennis            // Synchronous mode always signals that an additional frame should
572bd5404d0312752e7c8946e8540129f0d2d97bcd7Jamie Gennis            // be consumed.
573bd5404d0312752e7c8946e8540129f0d2d97bcd7Jamie Gennis            listener = mFrameAvailableListener;
5745bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian        } else {
575bd5404d0312752e7c8946e8540129f0d2d97bcd7Jamie Gennis            // In asynchronous mode we only keep the most recent buffer.
576a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis            if (mQueue.empty()) {
577a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis                mQueue.push_back(buf);
578bd5404d0312752e7c8946e8540129f0d2d97bcd7Jamie Gennis
579bd5404d0312752e7c8946e8540129f0d2d97bcd7Jamie Gennis                // Asynchronous mode only signals that a frame should be
580bd5404d0312752e7c8946e8540129f0d2d97bcd7Jamie Gennis                // consumed if no previous frame was pending. If a frame were
581bd5404d0312752e7c8946e8540129f0d2d97bcd7Jamie Gennis                // pending then the consumer would have already been notified.
582bd5404d0312752e7c8946e8540129f0d2d97bcd7Jamie Gennis                listener = mFrameAvailableListener;
583a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis            } else {
584a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis                Fifo::iterator front(mQueue.begin());
585a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis                // buffer currently queued is freed
586a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis                mSlots[*front].mBufferState = BufferSlot::FREE;
587a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis                // and we record the new buffer index in the queued list
588a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis                *front = buf;
589a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis            }
5905bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian        }
5915bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian
592a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis        mSlots[buf].mBufferState = BufferSlot::QUEUED;
593a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis        mSlots[buf].mCrop = mNextCrop;
594a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis        mSlots[buf].mTransform = mNextTransform;
59509d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian        mSlots[buf].mScalingMode = mNextScalingMode;
596a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis        mSlots[buf].mTimestamp = timestamp;
597f1e868f68204bf469a0c162b84af0e651d513ac8Sunita Nadampalli        mFrameCounter++;
598f1e868f68204bf469a0c162b84af0e651d513ac8Sunita Nadampalli        mSlots[buf].mFrameNumber = mFrameCounter;
599f1e868f68204bf469a0c162b84af0e651d513ac8Sunita Nadampalli
600a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis        mDequeueCondition.signal();
6011a227437be33157175b4de5f47d08a02647ee71aMathias Agopian
6021a227437be33157175b4de5f47d08a02647ee71aMathias Agopian        *outWidth = mDefaultWidth;
6031a227437be33157175b4de5f47d08a02647ee71aMathias Agopian        *outHeight = mDefaultHeight;
6041a227437be33157175b4de5f47d08a02647ee71aMathias Agopian        *outTransform = 0;
605e845c352c8eb93412fa7caedb5435d3597c795d0Mathias Agopian    } // scope for the lock
6065bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian
607e845c352c8eb93412fa7caedb5435d3597c795d0Mathias Agopian    // call back without lock held
608e845c352c8eb93412fa7caedb5435d3597c795d0Mathias Agopian    if (listener != 0) {
609e845c352c8eb93412fa7caedb5435d3597c795d0Mathias Agopian        listener->onFrameAvailable();
610376590d668e22a918439877b55faf075427b13f3Jamie Gennis    }
61168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    return OK;
61268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
61368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
61468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennisvoid SurfaceTexture::cancelBuffer(int buf) {
615e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("cancelBuffer: slot=%d", buf);
61668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    Mutex::Autolock lock(mMutex);
6175ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis
6185ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    if (mAbandoned) {
61944a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis        ST_LOGW("cancelBuffer: SurfaceTexture has been abandoned!");
6205ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis        return;
6215ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    }
6225ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis
6235bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian    if (buf < 0 || buf >= mBufferCount) {
62444a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis        ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
6255bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian                mBufferCount, buf);
62668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        return;
6275bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian    } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
62844a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis        ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
6295bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian                buf, mSlots[buf].mBufferState);
63068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        return;
63168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    }
6325bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian    mSlots[buf].mBufferState = BufferSlot::FREE;
633f1e868f68204bf469a0c162b84af0e651d513ac8Sunita Nadampalli    mSlots[buf].mFrameNumber = 0;
6345bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian    mDequeueCondition.signal();
63568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
63668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
637b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatus_t SurfaceTexture::setCrop(const Rect& crop) {
638e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("setCrop: crop=[%d,%d,%d,%d]", crop.left, crop.top, crop.right,
639e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis            crop.bottom);
640e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis
64168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    Mutex::Autolock lock(mMutex);
6425ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    if (mAbandoned) {
64344a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis        ST_LOGE("setCrop: SurfaceTexture has been abandoned!");
6445ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis        return NO_INIT;
6455ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    }
646b598fb90727be45e926a11abefc319819a733540Jamie Gennis    mNextCrop = crop;
64768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    return OK;
64868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
64968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
65068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennisstatus_t SurfaceTexture::setTransform(uint32_t transform) {
651e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("setTransform: xform=%#x", transform);
65268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    Mutex::Autolock lock(mMutex);
6535ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    if (mAbandoned) {
65444a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis        ST_LOGE("setTransform: SurfaceTexture has been abandoned!");
6555ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis        return NO_INIT;
6565ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    }
657b598fb90727be45e926a11abefc319819a733540Jamie Gennis    mNextTransform = transform;
65868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    return OK;
65968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
66068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
661053b02df2d350466a2226a90709e50fedef54747Mathias Agopianstatus_t SurfaceTexture::connect(int api,
662053b02df2d350466a2226a90709e50fedef54747Mathias Agopian        uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
663e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("connect: api=%d", api);
6649709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis    Mutex::Autolock lock(mMutex);
6655ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis
6665ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    if (mAbandoned) {
66744a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis        ST_LOGE("connect: SurfaceTexture has been abandoned!");
6685ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis        return NO_INIT;
6695ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    }
6705ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis
6719709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis    int err = NO_ERROR;
6729709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis    switch (api) {
6739709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis        case NATIVE_WINDOW_API_EGL:
6749709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis        case NATIVE_WINDOW_API_CPU:
6759709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis        case NATIVE_WINDOW_API_MEDIA:
6769709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis        case NATIVE_WINDOW_API_CAMERA:
6779709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis            if (mConnectedApi != NO_CONNECTED_API) {
67844a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis                ST_LOGE("connect: already connected (cur=%d, req=%d)",
679949be32b671304d5281ac0abbf30dcf4ebaa9eafMathias Agopian                        mConnectedApi, api);
6809709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis                err = -EINVAL;
6819709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis            } else {
6829709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis                mConnectedApi = api;
683053b02df2d350466a2226a90709e50fedef54747Mathias Agopian                *outWidth = mDefaultWidth;
684053b02df2d350466a2226a90709e50fedef54747Mathias Agopian                *outHeight = mDefaultHeight;
685053b02df2d350466a2226a90709e50fedef54747Mathias Agopian                *outTransform = 0;
6869709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis            }
6879709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis            break;
6889709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis        default:
6899709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis            err = -EINVAL;
6909709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis            break;
6919709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis    }
6929709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis    return err;
6939709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis}
6949709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis
6959709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennisstatus_t SurfaceTexture::disconnect(int api) {
696e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("disconnect: api=%d", api);
6979709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis    Mutex::Autolock lock(mMutex);
6985ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis
6995ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    if (mAbandoned) {
700b05bb17eebe631637cf9fa3af00758e8159d6e8dMathias Agopian        // it is not really an error to disconnect after the surface
701b05bb17eebe631637cf9fa3af00758e8159d6e8dMathias Agopian        // has been abandoned, it should just be a no-op.
702b05bb17eebe631637cf9fa3af00758e8159d6e8dMathias Agopian        return NO_ERROR;
7035ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    }
7045ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis
7059709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis    int err = NO_ERROR;
7069709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis    switch (api) {
7079709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis        case NATIVE_WINDOW_API_EGL:
7089709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis        case NATIVE_WINDOW_API_CPU:
7099709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis        case NATIVE_WINDOW_API_MEDIA:
7109709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis        case NATIVE_WINDOW_API_CAMERA:
7119709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis            if (mConnectedApi == api) {
7125c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian                drainQueueAndFreeBuffersLocked();
7139709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis                mConnectedApi = NO_CONNECTED_API;
7142370d0a14f09d4fb5133ff48e28459ce8343bf80Mathias Agopian                mNextCrop.makeInvalid();
7152370d0a14f09d4fb5133ff48e28459ce8343bf80Mathias Agopian                mNextScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
7162370d0a14f09d4fb5133ff48e28459ce8343bf80Mathias Agopian                mNextTransform = 0;
7175c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian                mDequeueCondition.signal();
7189709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis            } else {
71944a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis                ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)",
720949be32b671304d5281ac0abbf30dcf4ebaa9eafMathias Agopian                        mConnectedApi, api);
7219709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis                err = -EINVAL;
7229709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis            }
7239709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis            break;
7249709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis        default:
725e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis            ST_LOGE("disconnect: unknown API %d", api);
7269709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis            err = -EINVAL;
7279709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis            break;
7289709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis    }
7299709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis    return err;
7309709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis}
7319709687463dc5f1255f435e57b3d2beed8b70330Jamie Gennis
73209d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopianstatus_t SurfaceTexture::setScalingMode(int mode) {
733e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("setScalingMode: mode=%d", mode);
73409d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian
73509d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian    switch (mode) {
73609d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian        case NATIVE_WINDOW_SCALING_MODE_FREEZE:
73709d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian        case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
73809d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian            break;
73909d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian        default:
740e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis            ST_LOGE("unknown scaling mode: %d", mode);
74109d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian            return BAD_VALUE;
74209d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian    }
74309d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian
74409d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian    Mutex::Autolock lock(mMutex);
74509d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian    mNextScalingMode = mode;
74609d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian    return OK;
74709d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian}
74809d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian
74968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennisstatus_t SurfaceTexture::updateTexImage() {
750e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("updateTexImage");
75168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    Mutex::Autolock lock(mMutex);
75268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
75395dfd05c2c13735e5dbc1ae9e06fdba1053ffd8eMathias Agopian    if (mAbandoned) {
75444a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis        ST_LOGE("calling updateTexImage() on an abandoned SurfaceTexture");
7555c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian        return NO_INIT;
75695dfd05c2c13735e5dbc1ae9e06fdba1053ffd8eMathias Agopian    }
75795dfd05c2c13735e5dbc1ae9e06fdba1053ffd8eMathias Agopian
7589fb5976367911d0ab42d296238f0f06d517e867dJamie Gennis    // In asynchronous mode the list is guaranteed to be one buffer
7599fb5976367911d0ab42d296238f0f06d517e867dJamie Gennis    // deep, while in synchronous mode we use the oldest buffer.
7605bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian    if (!mQueue.empty()) {
7615bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian        Fifo::iterator front(mQueue.begin());
7629fb5976367911d0ab42d296238f0f06d517e867dJamie Gennis        int buf = *front;
7635bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian
764b598fb90727be45e926a11abefc319819a733540Jamie Gennis        // Update the GL texture object.
7655bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian        EGLImageKHR image = mSlots[buf].mEglImage;
76677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        EGLDisplay dpy = eglGetCurrentDisplay();
76768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        if (image == EGL_NO_IMAGE_KHR) {
76895dfd05c2c13735e5dbc1ae9e06fdba1053ffd8eMathias Agopian            if (mSlots[buf].mGraphicBuffer == 0) {
76944a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis                ST_LOGE("buffer at slot %d is null", buf);
7705c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian                return BAD_VALUE;
77195dfd05c2c13735e5dbc1ae9e06fdba1053ffd8eMathias Agopian            }
7725bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian            image = createImage(dpy, mSlots[buf].mGraphicBuffer);
7735bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian            mSlots[buf].mEglImage = image;
7745bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian            mSlots[buf].mEglDisplay = dpy;
7756fad64c747040e6abcc6a57b99e5ba9293ee4d99Mathias Agopian            if (image == EGL_NO_IMAGE_KHR) {
7766fad64c747040e6abcc6a57b99e5ba9293ee4d99Mathias Agopian                // NOTE: if dpy was invalid, createImage() is guaranteed to
7776fad64c747040e6abcc6a57b99e5ba9293ee4d99Mathias Agopian                // fail. so we'd end up here.
7786fad64c747040e6abcc6a57b99e5ba9293ee4d99Mathias Agopian                return -EINVAL;
7796fad64c747040e6abcc6a57b99e5ba9293ee4d99Mathias Agopian            }
78068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        }
78179d01fe8232c67a18aeb8784c2b8783358ec4e44Jamie Gennis
78279d01fe8232c67a18aeb8784c2b8783358ec4e44Jamie Gennis        GLint error;
78379d01fe8232c67a18aeb8784c2b8783358ec4e44Jamie Gennis        while ((error = glGetError()) != GL_NO_ERROR) {
78444a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis            ST_LOGW("updateTexImage: clearing GL error: %#04x", error);
78579d01fe8232c67a18aeb8784c2b8783358ec4e44Jamie Gennis        }
78627cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian
7878606fefa219d63d0a0f3df1b9dcf49cfbfa5b3e5Jamie Gennis        glBindTexture(mTexTarget, mTexName);
7888606fefa219d63d0a0f3df1b9dcf49cfbfa5b3e5Jamie Gennis        glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image);
78927cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian
79079d01fe8232c67a18aeb8784c2b8783358ec4e44Jamie Gennis        bool failed = false;
79179d01fe8232c67a18aeb8784c2b8783358ec4e44Jamie Gennis        while ((error = glGetError()) != GL_NO_ERROR) {
79244a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis            ST_LOGE("error binding external texture image %p (slot %d): %#04x",
7935bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian                    image, buf, error);
79479d01fe8232c67a18aeb8784c2b8783358ec4e44Jamie Gennis            failed = true;
79579d01fe8232c67a18aeb8784c2b8783358ec4e44Jamie Gennis        }
79679d01fe8232c67a18aeb8784c2b8783358ec4e44Jamie Gennis        if (failed) {
79768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            return -EINVAL;
79868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        }
799f7acf162f8d682c6ebc9af41ca76795b79509193Jamie Gennis
80077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        if (mCurrentTexture != INVALID_BUFFER_SLOT) {
80177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            if (mUseFenceSync) {
80277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                EGLSyncKHR fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR,
80377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                        NULL);
80477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                if (fence == EGL_NO_SYNC_KHR) {
80577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                    LOGE("updateTexImage: error creating fence: %#x",
80677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                            eglGetError());
80777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                    return -EINVAL;
80877cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                }
80977cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                glFlush();
81077cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                mSlots[mCurrentTexture].mFence = fence;
81177cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            }
81277cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        }
81377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis
81477cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis        ST_LOGV("updateTexImage: (slot=%d buf=%p) -> (slot=%d buf=%p)",
81577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                mCurrentTexture,
81677cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                mCurrentTextureBuf != NULL ? mCurrentTextureBuf->handle : 0,
81777cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis                buf, mSlots[buf].mGraphicBuffer->handle);
818e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis
8195bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian        if (mCurrentTexture != INVALID_BUFFER_SLOT) {
8209fb5976367911d0ab42d296238f0f06d517e867dJamie Gennis            // The current buffer becomes FREE if it was still in the queued
8215bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian            // state. If it has already been given to the client
8225bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian            // (synchronous mode), then it stays in DEQUEUED state.
82377cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            if (mSlots[mCurrentTexture].mBufferState == BufferSlot::QUEUED) {
8245bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian                mSlots[mCurrentTexture].mBufferState = BufferSlot::FREE;
82577cec6132aea6ed98812125f5ad5f79e889cf658Jamie Gennis            }
8265bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian        }
8275bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian
828f7acf162f8d682c6ebc9af41ca76795b79509193Jamie Gennis        // Update the SurfaceTexture state.
8295bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian        mCurrentTexture = buf;
8305bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian        mCurrentTextureBuf = mSlots[buf].mGraphicBuffer;
831a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis        mCurrentCrop = mSlots[buf].mCrop;
832a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis        mCurrentTransform = mSlots[buf].mTransform;
83309d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian        mCurrentScalingMode = mSlots[buf].mScalingMode;
834a218715a7fca98c868feccee4751c94e38b676ffJamie Gennis        mCurrentTimestamp = mSlots[buf].mTimestamp;
835eadfb673e7b346af02a925ad04494100db1ebbf7Jamie Gennis        computeCurrentTransformMatrix();
8369fb5976367911d0ab42d296238f0f06d517e867dJamie Gennis
8379fb5976367911d0ab42d296238f0f06d517e867dJamie Gennis        // Now that we've passed the point at which failures can happen,
8389fb5976367911d0ab42d296238f0f06d517e867dJamie Gennis        // it's safe to remove the buffer from the front of the queue.
8399fb5976367911d0ab42d296238f0f06d517e867dJamie Gennis        mQueue.erase(front);
8405bbb1cf9d7f9ecb8a2fc5ca8ba51c222c2aaff16Mathias Agopian        mDequeueCondition.signal();
84127cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    } else {
84227cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian        // We always bind the texture even if we don't update its contents.
8438606fefa219d63d0a0f3df1b9dcf49cfbfa5b3e5Jamie Gennis        glBindTexture(mTexTarget, mTexName);
84468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    }
8459fb5976367911d0ab42d296238f0f06d517e867dJamie Gennis
84668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    return OK;
84768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
84868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
84927cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopianbool SurfaceTexture::isExternalFormat(uint32_t format)
85027cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian{
85127cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    switch (format) {
85227cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    // supported YUV formats
85327cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    case HAL_PIXEL_FORMAT_YV12:
85427cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    // Legacy/deprecated YUV formats
85527cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
85627cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
85727cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    case HAL_PIXEL_FORMAT_YCbCr_422_I:
85827cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian        return true;
85927cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    }
86027cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian
86127cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    // Any OEM format needs to be considered
86227cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    if (format>=0x100 && format<=0x1FF)
86327cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian        return true;
86427cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian
86527cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    return false;
86627cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian}
86727cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian
86827cd07ca8006fd80d85379ada416874bfa78aa88Mathias AgopianGLenum SurfaceTexture::getCurrentTextureTarget() const {
8698606fefa219d63d0a0f3df1b9dcf49cfbfa5b3e5Jamie Gennis    return mTexTarget;
87027cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian}
87127cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian
872b598fb90727be45e926a11abefc319819a733540Jamie Gennisvoid SurfaceTexture::getTransformMatrix(float mtx[16]) {
873b598fb90727be45e926a11abefc319819a733540Jamie Gennis    Mutex::Autolock lock(mMutex);
874eadfb673e7b346af02a925ad04494100db1ebbf7Jamie Gennis    memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix));
875eadfb673e7b346af02a925ad04494100db1ebbf7Jamie Gennis}
876eadfb673e7b346af02a925ad04494100db1ebbf7Jamie Gennis
877eadfb673e7b346af02a925ad04494100db1ebbf7Jamie Gennisvoid SurfaceTexture::computeCurrentTransformMatrix() {
878e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("computeCurrentTransformMatrix");
879b598fb90727be45e926a11abefc319819a733540Jamie Gennis
8800fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    float xform[16];
8810fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    for (int i = 0; i < 16; i++) {
8820fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        xform[i] = mtxIdentity[i];
8830fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    }
8840fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
8850fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        float result[16];
8860fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        mtxMul(result, xform, mtxFlipH);
8870fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        for (int i = 0; i < 16; i++) {
8880fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis            xform[i] = result[i];
8890fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        }
8900fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    }
8910fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) {
8920fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        float result[16];
8930fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        mtxMul(result, xform, mtxFlipV);
8940fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        for (int i = 0; i < 16; i++) {
8950fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis            xform[i] = result[i];
8960fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        }
8970fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    }
8980fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
8990fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        float result[16];
9000fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        mtxMul(result, xform, mtxRot90);
9010fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        for (int i = 0; i < 16; i++) {
9020fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis            xform[i] = result[i];
9030fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        }
904b598fb90727be45e926a11abefc319819a733540Jamie Gennis    }
905b598fb90727be45e926a11abefc319819a733540Jamie Gennis
906b598fb90727be45e926a11abefc319819a733540Jamie Gennis    sp<GraphicBuffer>& buf(mSlots[mCurrentTexture].mGraphicBuffer);
9070fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    float tx, ty, sx, sy;
9080fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    if (!mCurrentCrop.isEmpty()) {
909f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        // In order to prevent bilinear sampling at the of the crop rectangle we
910f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        // may need to shrink it by 2 texels in each direction.  Normally this
911f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        // would just need to take 1/2 a texel off each end, but because the
912f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        // chroma channels will likely be subsampled we need to chop off a whole
913f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        // texel.  This will cause artifacts if someone does nearest sampling
914f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        // with 1:1 pixel:texel ratio, but it's impossible to simultaneously
915f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        // accomodate the bilinear and nearest sampling uses.
916f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        //
917f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        // If nearest sampling turns out to be a desirable usage of these
918f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        // textures then we could add the ability to switch a SurfaceTexture to
919f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        // nearest-mode.  Preferably, however, the image producers (video
920f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        // decoder, camera, etc.) would simply not use a crop rectangle (or at
921f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        // least not tell the framework about it) so that the GPU can do the
922f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        // correct edge behavior.
923f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        int xshrink = 0, yshrink = 0;
924f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        if (mCurrentCrop.left > 0) {
925f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis            tx = float(mCurrentCrop.left + 1) / float(buf->getWidth());
926f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis            xshrink++;
927f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        } else {
928f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis            tx = 0.0f;
929f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        }
930e5a1bffd9106b1d82259de1a202e1f2f28742392Mathias Agopian        if (mCurrentCrop.right < int32_t(buf->getWidth())) {
931f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis            xshrink++;
932f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        }
933e5a1bffd9106b1d82259de1a202e1f2f28742392Mathias Agopian        if (mCurrentCrop.bottom < int32_t(buf->getHeight())) {
934f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis            ty = (float(buf->getHeight() - mCurrentCrop.bottom) + 1.0f) /
935f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis                    float(buf->getHeight());
936f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis            yshrink++;
937f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        } else {
938f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis            ty = 0.0f;
939f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        }
940f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        if (mCurrentCrop.top > 0) {
941f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis            yshrink++;
942f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        }
943f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        sx = float(mCurrentCrop.width() - xshrink) / float(buf->getWidth());
944f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        sy = float(mCurrentCrop.height() - yshrink) / float(buf->getHeight());
9450fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    } else {
9460fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        tx = 0.0f;
9470fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        ty = 0.0f;
9480fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        sx = 1.0f;
9490fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        sy = 1.0f;
9500fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    }
951b598fb90727be45e926a11abefc319819a733540Jamie Gennis    float crop[16] = {
9520fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        sx, 0, 0, 0,
9530fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis        0, sy, 0, 0,
954b598fb90727be45e926a11abefc319819a733540Jamie Gennis        0, 0, 1, 0,
955f3cedb602197a6255e3a7b005cc368577d75bf3aJamie Gennis        tx, ty, 0, 1,
956b598fb90727be45e926a11abefc319819a733540Jamie Gennis    };
957b598fb90727be45e926a11abefc319819a733540Jamie Gennis
9580fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    float mtxBeforeFlipV[16];
9590fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    mtxMul(mtxBeforeFlipV, crop, xform);
9600fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis
9610fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    // SurfaceFlinger expects the top of its window textures to be at a Y
9620fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    // coordinate of 0, so SurfaceTexture must behave the same way.  We don't
9630fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    // want to expose this to applications, however, so we must add an
9640fb736c0937d9d65001e0176d90e1011226594bfJamie Gennis    // additional vertical flip to the transform after all the other transforms.
965eadfb673e7b346af02a925ad04494100db1ebbf7Jamie Gennis    mtxMul(mCurrentTransformMatrix, mtxFlipV, mtxBeforeFlipV);
966b598fb90727be45e926a11abefc319819a733540Jamie Gennis}
967b598fb90727be45e926a11abefc319819a733540Jamie Gennis
968c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvalansecs_t SurfaceTexture::getTimestamp() {
969e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("getTimestamp");
970c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala    Mutex::Autolock lock(mMutex);
971c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala    return mCurrentTimestamp;
972c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala}
973c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala
974376590d668e22a918439877b55faf075427b13f3Jamie Gennisvoid SurfaceTexture::setFrameAvailableListener(
975c9ec69eb6f07881e1d0582156e5697eff69f5546Pannag Sanketi        const sp<FrameAvailableListener>& listener) {
976e4bd0f32a39898ca25bc45f93b01ea2cc4a235a4Jamie Gennis    ST_LOGV("setFrameAvailableListener");
977376590d668e22a918439877b55faf075427b13f3Jamie Gennis    Mutex::Autolock lock(mMutex);
978c9ec69eb6f07881e1d0582156e5697eff69f5546Pannag Sanketi    mFrameAvailableListener = listener;
979376590d668e22a918439877b55faf075427b13f3Jamie Gennis}
980376590d668e22a918439877b55faf075427b13f3Jamie Gennis
9815c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopianvoid SurfaceTexture::freeBufferLocked(int i) {
9825c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian    mSlots[i].mGraphicBuffer = 0;
9835c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian    mSlots[i].mBufferState = BufferSlot::FREE;
984f1e868f68204bf469a0c162b84af0e651d513ac8Sunita Nadampalli    mSlots[i].mFrameNumber = 0;
9855c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian    if (mSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
9865c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian        eglDestroyImageKHR(mSlots[i].mEglDisplay, mSlots[i].mEglImage);
9875c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian        mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
9885c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian        mSlots[i].mEglDisplay = EGL_NO_DISPLAY;
9895c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian    }
9905c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian}
9915c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian
992a04cda9986366ab480ad8008c4d923271b05d78eMathias Agopianvoid SurfaceTexture::freeAllBuffersLocked() {
993a04cda9986366ab480ad8008c4d923271b05d78eMathias Agopian    LOGW_IF(!mQueue.isEmpty(),
994a04cda9986366ab480ad8008c4d923271b05d78eMathias Agopian            "freeAllBuffersLocked called but mQueue is not empty");
9958618ebcc5d20a5983da1fc6200d50c3662aca6e3Mathias Agopian    mCurrentTexture = INVALID_BUFFER_SLOT;
99668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
9975c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian        freeBufferLocked(i);
9985c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian    }
9995c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian}
10005c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian
10015c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopianvoid SurfaceTexture::freeAllBuffersExceptHeadLocked() {
10025c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian    LOGW_IF(!mQueue.isEmpty(),
10035c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian            "freeAllBuffersExceptCurrentLocked called but mQueue is not empty");
10045c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian    int head = -1;
10055c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian    if (!mQueue.empty()) {
10065c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian        Fifo::iterator front(mQueue.begin());
10075c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian        head = *front;
10085c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian    }
10098618ebcc5d20a5983da1fc6200d50c3662aca6e3Mathias Agopian    mCurrentTexture = INVALID_BUFFER_SLOT;
10105c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
10115c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian        if (i != head) {
10125c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian            freeBufferLocked(i);
101368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        }
101468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    }
101568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
101668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
10175c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopianstatus_t SurfaceTexture::drainQueueLocked() {
101871fd1213b49e6a33bea42348876eb1db2ab3d362Mathias Agopian    while (mSynchronousMode && !mQueue.isEmpty()) {
101971fd1213b49e6a33bea42348876eb1db2ab3d362Mathias Agopian        mDequeueCondition.wait(mMutex);
10205c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian        if (mAbandoned) {
102144a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis            ST_LOGE("drainQueueLocked: SurfaceTexture has been abandoned!");
10225c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian            return NO_INIT;
10235c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian        }
10245c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian        if (mConnectedApi == NO_CONNECTED_API) {
102544a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis            ST_LOGE("drainQueueLocked: SurfaceTexture is not connected!");
10265c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian            return NO_INIT;
10275c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian        }
102871fd1213b49e6a33bea42348876eb1db2ab3d362Mathias Agopian    }
10295c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian    return NO_ERROR;
10305c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian}
10315c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian
10325c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopianstatus_t SurfaceTexture::drainQueueAndFreeBuffersLocked() {
10335c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian    status_t err = drainQueueLocked();
10345c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian    if (err == NO_ERROR) {
10355c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian        if (mSynchronousMode) {
10365c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian            freeAllBuffersLocked();
10375c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian        } else {
10385c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian            freeAllBuffersExceptHeadLocked();
10395c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian        }
10405c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian    }
10415c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian    return err;
104271fd1213b49e6a33bea42348876eb1db2ab3d362Mathias Agopian}
104371fd1213b49e6a33bea42348876eb1db2ab3d362Mathias Agopian
104468e4a7ac849b681b1fb769857fc04f64262480c4Jamie GennisEGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy,
104568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        const sp<GraphicBuffer>& graphicBuffer) {
104668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    EGLClientBuffer cbuf = (EGLClientBuffer)graphicBuffer->getNativeBuffer();
104768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    EGLint attrs[] = {
104868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE,
104968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        EGL_NONE,
105068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    };
105168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT,
105268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs);
10536fad64c747040e6abcc6a57b99e5ba9293ee4d99Mathias Agopian    if (image == EGL_NO_IMAGE_KHR) {
10546fad64c747040e6abcc6a57b99e5ba9293ee4d99Mathias Agopian        EGLint error = eglGetError();
105544a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis        ST_LOGE("error creating EGLImage: %#x", error);
105668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    }
105768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    return image;
105868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
105968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
106027cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopiansp<GraphicBuffer> SurfaceTexture::getCurrentBuffer() const {
106127cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    Mutex::Autolock lock(mMutex);
106227cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    return mCurrentTextureBuf;
106327cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian}
106427cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian
106527cd07ca8006fd80d85379ada416874bfa78aa88Mathias AgopianRect SurfaceTexture::getCurrentCrop() const {
106627cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    Mutex::Autolock lock(mMutex);
106727cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    return mCurrentCrop;
106827cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian}
106927cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian
107027cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopianuint32_t SurfaceTexture::getCurrentTransform() const {
107127cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    Mutex::Autolock lock(mMutex);
107227cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian    return mCurrentTransform;
107327cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian}
107427cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian
107509d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopianuint32_t SurfaceTexture::getCurrentScalingMode() const {
107609d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian    Mutex::Autolock lock(mMutex);
107709d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian    return mCurrentScalingMode;
107809d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian}
107909d7ed7b395d66be97c6bcb052039f5c0dce646cMathias Agopian
108087f3265bb082160efdfdfb87a79698c67ebad447Jamie Gennisbool SurfaceTexture::isSynchronousMode() const {
108187f3265bb082160efdfdfb87a79698c67ebad447Jamie Gennis    Mutex::Autolock lock(mMutex);
108287f3265bb082160efdfdfb87a79698c67ebad447Jamie Gennis    return mSynchronousMode;
108387f3265bb082160efdfdfb87a79698c67ebad447Jamie Gennis}
108487f3265bb082160efdfdfb87a79698c67ebad447Jamie Gennis
1085ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopianint SurfaceTexture::query(int what, int* outValue)
1086ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian{
1087ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian    Mutex::Autolock lock(mMutex);
10885ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis
10895ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    if (mAbandoned) {
109044a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis        ST_LOGE("query: SurfaceTexture has been abandoned!");
10915ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis        return NO_INIT;
10925ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    }
10935ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis
1094ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian    int value;
1095ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian    switch (what) {
1096ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian    case NATIVE_WINDOW_WIDTH:
1097ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian        value = mDefaultWidth;
1098ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian        break;
1099ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian    case NATIVE_WINDOW_HEIGHT:
1100ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian        value = mDefaultHeight;
1101ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian        break;
1102ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian    case NATIVE_WINDOW_FORMAT:
1103ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian        value = mPixelFormat;
1104ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian        break;
1105ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian    case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
1106ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian        value = mSynchronousMode ?
1107ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian                (MIN_UNDEQUEUED_BUFFERS-1) : MIN_UNDEQUEUED_BUFFERS;
1108ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian        break;
1109ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian    default:
1110ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian        return BAD_VALUE;
1111ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian    }
1112ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian    outValue[0] = value;
1113ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian    return NO_ERROR;
1114ed3894c07a67b3e35d07084c4a8b410908bfedc5Mathias Agopian}
111527cd07ca8006fd80d85379ada416874bfa78aa88Mathias Agopian
11165ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennisvoid SurfaceTexture::abandon() {
11175ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    Mutex::Autolock lock(mMutex);
11185c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian    mQueue.clear();
11195ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    mAbandoned = true;
1120ec46b4e1ca89d7c3a9ad70ded58da08b5e19f08fMathias Agopian    mCurrentTextureBuf.clear();
11215c71575983e96e6e4c5149e7e39d92f760f5c1fcMathias Agopian    freeAllBuffersLocked();
11225ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis    mDequeueCondition.signal();
11235ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis}
11245ef59bc764d6bcd0ccf0a266d7d9ab792668a3e9Jamie Gennis
112544a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennisvoid SurfaceTexture::setName(const String8& name) {
112644a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis    mName = name;
112744a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis}
112844a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis
11297f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopianvoid SurfaceTexture::dump(String8& result) const
11307f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian{
11317f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian    char buffer[1024];
11327f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian    dump(result, "", buffer, 1024);
11337f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian}
11347f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian
11357f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopianvoid SurfaceTexture::dump(String8& result, const char* prefix,
11367f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian        char* buffer, size_t SIZE) const
11377f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian{
11387f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian    Mutex::Autolock _l(mMutex);
11397f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian    snprintf(buffer, SIZE,
11407f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian            "%smBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
11417f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian            "mPixelFormat=%d, mTexName=%d\n",
114244a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis            prefix, mBufferCount, mSynchronousMode, mDefaultWidth,
114344a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis            mDefaultHeight, mPixelFormat, mTexName);
11447f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian    result.append(buffer);
11457f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian
11467f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian    String8 fifo;
11477f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian    int fifoSize = 0;
11487f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian    Fifo::const_iterator i(mQueue.begin());
11497f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian    while (i != mQueue.end()) {
11507f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian        snprintf(buffer, SIZE, "%02d ", *i++);
11517f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian        fifoSize++;
11527f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian        fifo.append(buffer);
11537f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian    }
11547f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian
11557f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian    snprintf(buffer, SIZE,
1156ecfa1d3a7941a4f1a9c381c9c7419ecd0bd86967Jamie Gennis            "%scurrent: {crop=[%d,%d,%d,%d], transform=0x%02x, current=%d}\n"
11577f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian            "%snext   : {crop=[%d,%d,%d,%d], transform=0x%02x, FIFO(%d)={%s}}\n"
11587f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian            ,
11597f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian            prefix, mCurrentCrop.left,
11607f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian            mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom,
1161ecfa1d3a7941a4f1a9c381c9c7419ecd0bd86967Jamie Gennis            mCurrentTransform, mCurrentTexture,
116244a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis            prefix, mNextCrop.left, mNextCrop.top, mNextCrop.right,
116344a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis            mNextCrop.bottom, mNextTransform, fifoSize, fifo.string()
11647f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian    );
11657f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian    result.append(buffer);
11667f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian
11677f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian    struct {
11687f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian        const char * operator()(int state) const {
11697f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian            switch (state) {
11707f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian                case BufferSlot::DEQUEUED: return "DEQUEUED";
11717f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian                case BufferSlot::QUEUED: return "QUEUED";
11727f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian                case BufferSlot::FREE: return "FREE";
11737f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian                default: return "Unknown";
11747f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian            }
11757f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian        }
11767f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian    } stateName;
11777f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian
11787f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian    for (int i=0 ; i<mBufferCount ; i++) {
11797f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian        const BufferSlot& slot(mSlots[i]);
11807f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian        snprintf(buffer, SIZE,
11810c3367f1bba78250ab9d05e105411ee326f8aee9Mathias Agopian                "%s%s[%02d] "
11820c3367f1bba78250ab9d05e105411ee326f8aee9Mathias Agopian                "state=%-8s, crop=[%d,%d,%d,%d], "
11834954193651ed7d48e35cfb64b14bb3fb3ff7a8a1Mathias Agopian                "transform=0x%02x, timestamp=%lld",
11840c3367f1bba78250ab9d05e105411ee326f8aee9Mathias Agopian                prefix, (i==mCurrentTexture)?">":" ", i,
11850c3367f1bba78250ab9d05e105411ee326f8aee9Mathias Agopian                stateName(slot.mBufferState),
118644a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis                slot.mCrop.left, slot.mCrop.top, slot.mCrop.right,
118744a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis                slot.mCrop.bottom, slot.mTransform, slot.mTimestamp
11887f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian        );
11897f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian        result.append(buffer);
11904954193651ed7d48e35cfb64b14bb3fb3ff7a8a1Mathias Agopian
11914954193651ed7d48e35cfb64b14bb3fb3ff7a8a1Mathias Agopian        const sp<GraphicBuffer>& buf(slot.mGraphicBuffer);
11924954193651ed7d48e35cfb64b14bb3fb3ff7a8a1Mathias Agopian        if (buf != NULL) {
11934954193651ed7d48e35cfb64b14bb3fb3ff7a8a1Mathias Agopian            snprintf(buffer, SIZE,
11944954193651ed7d48e35cfb64b14bb3fb3ff7a8a1Mathias Agopian                    ", %p [%4ux%4u:%4u,%3X]",
119544a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis                    buf->handle, buf->width, buf->height, buf->stride,
119644a052203e6c1c5453a74ebe94607b5c71b136ecJamie Gennis                    buf->format);
11974954193651ed7d48e35cfb64b14bb3fb3ff7a8a1Mathias Agopian            result.append(buffer);
11984954193651ed7d48e35cfb64b14bb3fb3ff7a8a1Mathias Agopian        }
11994954193651ed7d48e35cfb64b14bb3fb3ff7a8a1Mathias Agopian        result.append("\n");
12007f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian    }
12017f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian}
12027f3289c95ec489651f1c04f1a71cfc7a8b535805Mathias Agopian
1203b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]) {
1204b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3];
1205b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3];
1206b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3];
1207b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3];
1208b598fb90727be45e926a11abefc319819a733540Jamie Gennis
1209b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7];
1210b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7];
1211b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7];
1212b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7];
1213b598fb90727be45e926a11abefc319819a733540Jamie Gennis
1214b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11];
1215b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11];
1216b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11];
1217b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11];
1218b598fb90727be45e926a11abefc319819a733540Jamie Gennis
1219b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15];
1220b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15];
1221b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15];
1222b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15];
1223b598fb90727be45e926a11abefc319819a733540Jamie Gennis}
1224b598fb90727be45e926a11abefc319819a733540Jamie Gennis
122568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}; // namespace android
1226