GLConsumer.cpp revision 41f673c9b3aac0d96e41c928845c39186d565212
18ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis/* 28ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis * Copyright (C) 2010 The Android Open Source Project 38ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis * 48ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis * Licensed under the Apache License, Version 2.0 (the "License"); 58ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis * you may not use this file except in compliance with the License. 68ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis * You may obtain a copy of the License at 78ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis * 88ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis * http://www.apache.org/licenses/LICENSE-2.0 98ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis * 108ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis * Unless required by applicable law or agreed to in writing, software 118ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis * distributed under the License is distributed on an "AS IS" BASIS, 128ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis * See the License for the specific language governing permissions and 148ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis * limitations under the License. 158ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis */ 168ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 178ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#define LOG_TAG "SurfaceTexture" 18e70d8b43938e17beebcc0c97a9373a1906f6f2bfJamie Gennis//#define LOG_NDEBUG 0 198ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 208ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#define GL_GLEXT_PROTOTYPES 218ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#define EGL_EGLEXT_PROTOTYPES 228ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 238ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <EGL/egl.h> 248ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <EGL/eglext.h> 258ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <GLES2/gl2.h> 268ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <GLES2/gl2ext.h> 278ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 288ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <gui/SurfaceTexture.h> 298ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 307a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian#include <hardware/hardware.h> 317a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 3241f673c9b3aac0d96e41c928845c39186d565212Mathias Agopian#include <private/gui/ComposerService.h> 3341f673c9b3aac0d96e41c928845c39186d565212Mathias Agopian 348ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <surfaceflinger/ISurfaceComposer.h> 358ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <surfaceflinger/SurfaceComposerClient.h> 369a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis#include <surfaceflinger/IGraphicBufferAlloc.h> 378ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 388ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <utils/Log.h> 3968c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian#include <utils/String8.h> 408ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 417c6eba666917308a64fadb0f0e08d7c041311976Mathias Agopian#ifdef ALLOW_DEQUEUE_CURRENT_BUFFER 427c6eba666917308a64fadb0f0e08d7c041311976Mathias Agopian#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER true 437c6eba666917308a64fadb0f0e08d7c041311976Mathias Agopian#warning "ALLOW_DEQUEUE_CURRENT_BUFFER enabled" 447c6eba666917308a64fadb0f0e08d7c041311976Mathias Agopian#else 457c6eba666917308a64fadb0f0e08d7c041311976Mathias Agopian#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER false 467c6eba666917308a64fadb0f0e08d7c041311976Mathias Agopian#endif 4729b5762efc359022168e5099c1d17925444d3147Mathias Agopian 48fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis// Macros for including the SurfaceTexture name in log messages 496807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block#define ST_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__) 50fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis#define ST_LOGD(x, ...) LOGD("[%s] "x, mName.string(), ##__VA_ARGS__) 51fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis#define ST_LOGI(x, ...) LOGI("[%s] "x, mName.string(), ##__VA_ARGS__) 52fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis#define ST_LOGW(x, ...) LOGW("[%s] "x, mName.string(), ##__VA_ARGS__) 53fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis#define ST_LOGE(x, ...) LOGE("[%s] "x, mName.string(), ##__VA_ARGS__) 5429b5762efc359022168e5099c1d17925444d3147Mathias Agopian 558ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennisnamespace android { 568ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 57f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis// Transform matrices 58f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxIdentity[16] = { 59f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 0, 60f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 61f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 62f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 0, 1, 63f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 64f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxFlipH[16] = { 65f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis -1, 0, 0, 0, 66f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 67f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 68f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 1, 69f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 70f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxFlipV[16] = { 71f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 0, 72f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, -1, 0, 0, 73f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 74f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 1, 75f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 76f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxRot90[16] = { 77f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 78f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis -1, 0, 0, 0, 79f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 80f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 1, 81f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 82f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxRot180[16] = { 83f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis -1, 0, 0, 0, 84f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, -1, 0, 0, 85f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 86f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 1, 0, 1, 87f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 88f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxRot270[16] = { 89f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, -1, 0, 0, 90f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 0, 91f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 92f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 1, 93f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 94f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 95f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]); 96f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 97fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis// Get an ID that's unique within this process. 98fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennisstatic int32_t createProcessUniqueId() { 99fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis static volatile int32_t globalCounter = 0; 100fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis return android_atomic_inc(&globalCounter); 101fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis} 102fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis 103fb1b5a2f333800574b0da435d1200cf9b13d723fJamie GennisSurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode, 104fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis GLenum texTarget) : 105a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian mDefaultWidth(1), 106a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian mDefaultHeight(1), 107a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian mPixelFormat(PIXEL_FORMAT_RGBA_8888), 1088072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian mBufferCount(MIN_ASYNC_BUFFER_SLOTS), 1098072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian mClientBufferCount(0), 1108072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS), 1111d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTexture(INVALID_BUFFER_SLOT), 1121d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTransform(0), 1131d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTimestamp(0), 1141d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mNextTransform(0), 1157734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian mNextScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 116b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mTexName(tex), 11714a0e58074f2698829b6554f578e6762c377caa3Grace Kloba mSynchronousMode(false), 118fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis mAllowSynchronousMode(allowSynchronousMode), 1197b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis mConnectedApi(NO_CONNECTED_API), 120fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis mAbandoned(false), 121a929748ddb67cbece3337c7fda7877fdeb973aa4Sunita Nadampalli mTexTarget(texTarget), 122a929748ddb67cbece3337c7fda7877fdeb973aa4Sunita Nadampalli mFrameCounter(0) { 123fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis // Choose a name using the PID and a process-unique ID. 124fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId()); 125fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis 1266ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("SurfaceTexture"); 1279a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis sp<ISurfaceComposer> composer(ComposerService::getComposerService()); 1289a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis mGraphicBufferAlloc = composer->createGraphicBufferAlloc(); 129cc57d6f8830e533734925f102307df2e6cff6de7Mathias Agopian mNextCrop.makeInvalid(); 130fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis memcpy(mCurrentTransformMatrix, mtxIdentity, 131fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis sizeof(mCurrentTransformMatrix)); 1328ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 1338ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 1348ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie GennisSurfaceTexture::~SurfaceTexture() { 1356ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("~SurfaceTexture"); 136ef51b992192adf4fc432686ab346f5fc7a13bc95Mathias Agopian freeAllBuffersLocked(); 1378ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 1388ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 1398072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopianstatus_t SurfaceTexture::setBufferCountServerLocked(int bufferCount) { 1408072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian if (bufferCount > NUM_BUFFER_SLOTS) 1418072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian return BAD_VALUE; 1428072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 1438072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // special-case, nothing to do 1448072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian if (bufferCount == mBufferCount) 1458072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian return OK; 1468072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 1478072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian if (!mClientBufferCount && 1488072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian bufferCount >= mBufferCount) { 1498072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // easy, we just have more buffers 1508072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian mBufferCount = bufferCount; 1518072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian mServerBufferCount = bufferCount; 1528072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian mDequeueCondition.signal(); 1538072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian } else { 1548072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // we're here because we're either 1558072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // - reducing the number of available buffers 1568072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // - or there is a client-buffer-count in effect 1578072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 1588072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // less than 2 buffers is never allowed 1598072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian if (bufferCount < 2) 1608072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian return BAD_VALUE; 1618072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 1628072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // when there is non client-buffer-count in effect, the client is not 1638072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // allowed to dequeue more than one buffer at a time, 1648072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // so the next time they dequeue a buffer, we know that they don't 1658072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // own one. the actual resizing will happen during the next 1668072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // dequeueBuffer. 1678072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 1688072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian mServerBufferCount = bufferCount; 1698072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian } 1708072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian return OK; 1718072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian} 1728072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 1738072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopianstatus_t SurfaceTexture::setBufferCountServer(int bufferCount) { 1748072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian Mutex::Autolock lock(mMutex); 1758072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian return setBufferCountServerLocked(bufferCount); 1768072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian} 1778072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 1788ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennisstatus_t SurfaceTexture::setBufferCount(int bufferCount) { 1796ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("setBufferCount: count=%d", bufferCount); 180b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian Mutex::Autolock lock(mMutex); 1819d4d6c101d90d4a1d1ca9413cf3eb89d1f1898d6Jamie Gennis 1827b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis if (mAbandoned) { 183fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("setBufferCount: SurfaceTexture has been abandoned!"); 1847b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis return NO_INIT; 1857b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis } 186292a31a4c2ae2f6faf134e8e4a726583017dad06Pannag Sanketi if (bufferCount > NUM_BUFFER_SLOTS) { 187fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("setBufferCount: bufferCount larger than slots available"); 188292a31a4c2ae2f6faf134e8e4a726583017dad06Pannag Sanketi return BAD_VALUE; 189292a31a4c2ae2f6faf134e8e4a726583017dad06Pannag Sanketi } 190292a31a4c2ae2f6faf134e8e4a726583017dad06Pannag Sanketi 1918072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // Error out if the user has dequeued buffers 1928072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian for (int i=0 ; i<mBufferCount ; i++) { 1938072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) { 194fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("setBufferCount: client owns some buffers"); 1958072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian return -EINVAL; 1968072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian } 1978072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian } 198b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 1991c121f68fc6ac4abff17203b55253d6aeee64bc5Jamie Gennis const int minBufferSlots = mSynchronousMode ? 2001c121f68fc6ac4abff17203b55253d6aeee64bc5Jamie Gennis MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS; 2018072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian if (bufferCount == 0) { 2028072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian mClientBufferCount = 0; 2038072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian bufferCount = (mServerBufferCount >= minBufferSlots) ? 2048072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian mServerBufferCount : minBufferSlots; 2058072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian return setBufferCountServerLocked(bufferCount); 2068072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian } 2078072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 2081c121f68fc6ac4abff17203b55253d6aeee64bc5Jamie Gennis if (bufferCount < minBufferSlots) { 209fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("setBufferCount: requested buffer count (%d) is less than " 2101c121f68fc6ac4abff17203b55253d6aeee64bc5Jamie Gennis "minimum (%d)", bufferCount, minBufferSlots); 2119d4d6c101d90d4a1d1ca9413cf3eb89d1f1898d6Jamie Gennis return BAD_VALUE; 2129d4d6c101d90d4a1d1ca9413cf3eb89d1f1898d6Jamie Gennis } 2139d4d6c101d90d4a1d1ca9413cf3eb89d1f1898d6Jamie Gennis 2148072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // here we're guaranteed that the client doesn't have dequeued buffers 2158072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // and will release all of its buffer references. 216ef51b992192adf4fc432686ab346f5fc7a13bc95Mathias Agopian freeAllBuffersLocked(); 2178ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis mBufferCount = bufferCount; 2188072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian mClientBufferCount = bufferCount; 21967eedd74ab78c2bfed9fcdc74947b97289254ca4Jamie Gennis mCurrentTexture = INVALID_BUFFER_SLOT; 220b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mQueue.clear(); 221b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mDequeueCondition.signal(); 2228ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return OK; 2238ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 2248ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 225a5c75c01620179ce00812354778a29a80d76e71fMathias Agopianstatus_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h) 226a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian{ 2276ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h); 2283fbce7c56082e4e0d23f1c1c89983d3841853ed7Mathias Agopian if (!w || !h) { 229fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)", 230fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis w, h); 2313fbce7c56082e4e0d23f1c1c89983d3841853ed7Mathias Agopian return BAD_VALUE; 232a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian } 2333fbce7c56082e4e0d23f1c1c89983d3841853ed7Mathias Agopian 2343fbce7c56082e4e0d23f1c1c89983d3841853ed7Mathias Agopian Mutex::Autolock lock(mMutex); 2353fbce7c56082e4e0d23f1c1c89983d3841853ed7Mathias Agopian mDefaultWidth = w; 2363fbce7c56082e4e0d23f1c1c89983d3841853ed7Mathias Agopian mDefaultHeight = h; 237a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian return OK; 238a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian} 239a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian 2407b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennisstatus_t SurfaceTexture::requestBuffer(int slot, sp<GraphicBuffer>* buf) { 2416ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("requestBuffer: slot=%d", slot); 2428ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis Mutex::Autolock lock(mMutex); 2437b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis if (mAbandoned) { 244fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("requestBuffer: SurfaceTexture has been abandoned!"); 2457b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis return NO_INIT; 2467b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis } 2477b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis if (slot < 0 || mBufferCount <= slot) { 248fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d", 2497b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis mBufferCount, slot); 2507b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis return BAD_VALUE; 2518ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 2527b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis mSlots[slot].mRequestBufferCalled = true; 2537b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis *buf = mSlots[slot].mGraphicBuffer; 2547b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis return NO_ERROR; 255c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian} 256c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian 257c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopianstatus_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, 258c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian uint32_t format, uint32_t usage) { 2596ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage); 260c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian 261292a31a4c2ae2f6faf134e8e4a726583017dad06Pannag Sanketi if ((w && !h) || (!w && h)) { 262fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h); 263c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian return BAD_VALUE; 264c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian } 265c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian 266c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian Mutex::Autolock lock(mMutex); 2678072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 2688072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian status_t returnFlags(OK); 2698072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 270a929748ddb67cbece3337c7fda7877fdeb973aa4Sunita Nadampalli int found = -1; 271a929748ddb67cbece3337c7fda7877fdeb973aa4Sunita Nadampalli int foundSync = -1; 272b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian int dequeuedCount = 0; 273b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian bool tryAgain = true; 274b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian while (tryAgain) { 2752560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian if (mAbandoned) { 276fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!"); 2772560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian return NO_INIT; 2782560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian } 2792560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian 2808072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // We need to wait for the FIFO to drain if the number of buffer 2818072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // needs to change. 2828072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // 2832560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian // The condition "number of buffers needs to change" is true if 2848072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // - the client doesn't care about how many buffers there are 2858072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // - AND the actual number of buffer is different from what was 2868072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // set in the last setBufferCountServer() 2878072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // - OR - 2888072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // setBufferCountServer() was set to a value incompatible with 2898072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // the synchronization mode (for instance because the sync mode 2908072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // changed since) 2918072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // 2928072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // As long as this condition is true AND the FIFO is not empty, we 2938072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // wait on mDequeueCondition. 2948072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 2952560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian const int minBufferCountNeeded = mSynchronousMode ? 2968072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS; 2978072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 2982560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian const bool numberOfBuffersNeedsToChange = !mClientBufferCount && 2998072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian ((mServerBufferCount != mBufferCount) || 3002560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian (mServerBufferCount < minBufferCountNeeded)); 3012560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian 3022560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian if (!mQueue.isEmpty() && numberOfBuffersNeedsToChange) { 3038072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // wait for the FIFO to drain 3042560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian mDequeueCondition.wait(mMutex); 3052560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian // NOTE: we continue here because we need to reevaluate our 3062560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian // whole state (eg: we could be abandoned or disconnected) 3072560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian continue; 3088072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian } 3098072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 3102560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian if (numberOfBuffersNeedsToChange) { 3118072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // here we're guaranteed that mQueue is empty 312ef51b992192adf4fc432686ab346f5fc7a13bc95Mathias Agopian freeAllBuffersLocked(); 3138072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian mBufferCount = mServerBufferCount; 3148072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian if (mBufferCount < minBufferCountNeeded) 3158072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian mBufferCount = minBufferCountNeeded; 3168072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian mCurrentTexture = INVALID_BUFFER_SLOT; 3178072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS; 3188072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian } 3198072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 3208072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // look for a free buffer to give to the client 321b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian found = INVALID_BUFFER_SLOT; 322b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian foundSync = INVALID_BUFFER_SLOT; 323b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian dequeuedCount = 0; 324b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian for (int i = 0; i < mBufferCount; i++) { 325b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian const int state = mSlots[i].mBufferState; 326b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian if (state == BufferSlot::DEQUEUED) { 327b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian dequeuedCount++; 328b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian } 32929b5762efc359022168e5099c1d17925444d3147Mathias Agopian 33029b5762efc359022168e5099c1d17925444d3147Mathias Agopian // if buffer is FREE it CANNOT be current 33129b5762efc359022168e5099c1d17925444d3147Mathias Agopian LOGW_IF((state == BufferSlot::FREE) && (mCurrentTexture==i), 33229b5762efc359022168e5099c1d17925444d3147Mathias Agopian "dequeueBuffer: buffer %d is both FREE and current!", i); 33329b5762efc359022168e5099c1d17925444d3147Mathias Agopian 3347c6eba666917308a64fadb0f0e08d7c041311976Mathias Agopian if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER) { 33529b5762efc359022168e5099c1d17925444d3147Mathias Agopian if (state == BufferSlot::FREE || i == mCurrentTexture) { 33629b5762efc359022168e5099c1d17925444d3147Mathias Agopian foundSync = i; 33729b5762efc359022168e5099c1d17925444d3147Mathias Agopian if (i != mCurrentTexture) { 33829b5762efc359022168e5099c1d17925444d3147Mathias Agopian found = i; 33929b5762efc359022168e5099c1d17925444d3147Mathias Agopian break; 34029b5762efc359022168e5099c1d17925444d3147Mathias Agopian } 34129b5762efc359022168e5099c1d17925444d3147Mathias Agopian } 34229b5762efc359022168e5099c1d17925444d3147Mathias Agopian } else { 34329b5762efc359022168e5099c1d17925444d3147Mathias Agopian if (state == BufferSlot::FREE) { 344a929748ddb67cbece3337c7fda7877fdeb973aa4Sunita Nadampalli /** For Asynchronous mode, we need to return the oldest of free buffers 345a929748ddb67cbece3337c7fda7877fdeb973aa4Sunita Nadampalli * There is only one instance when the Framecounter overflows, this logic 346a929748ddb67cbece3337c7fda7877fdeb973aa4Sunita Nadampalli * might return the earlier buffer to client. Which is a negligible impact 347a929748ddb67cbece3337c7fda7877fdeb973aa4Sunita Nadampalli **/ 348a929748ddb67cbece3337c7fda7877fdeb973aa4Sunita Nadampalli if (found < 0 || mSlots[i].mFrameNumber < mSlots[found].mFrameNumber) { 349a929748ddb67cbece3337c7fda7877fdeb973aa4Sunita Nadampalli foundSync = i; 350a929748ddb67cbece3337c7fda7877fdeb973aa4Sunita Nadampalli found = i; 351a929748ddb67cbece3337c7fda7877fdeb973aa4Sunita Nadampalli } 352b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian } 353b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian } 354b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian } 3558072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 3568072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // clients are not allowed to dequeue more than one buffer 3578072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // if they didn't set a buffer count. 3588072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian if (!mClientBufferCount && dequeuedCount) { 3596ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without " 3606ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis "setting the buffer count"); 3618072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian return -EINVAL; 3628072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian } 3638072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 364c2c8dfd71b84598f01074416e57cc3469d5b8ed2Jamie Gennis // See whether a buffer has been queued since the last setBufferCount so 365c2c8dfd71b84598f01074416e57cc3469d5b8ed2Jamie Gennis // we know whether to perform the MIN_UNDEQUEUED_BUFFERS check below. 366c2c8dfd71b84598f01074416e57cc3469d5b8ed2Jamie Gennis bool bufferHasBeenQueued = mCurrentTexture != INVALID_BUFFER_SLOT; 367c2c8dfd71b84598f01074416e57cc3469d5b8ed2Jamie Gennis if (bufferHasBeenQueued) { 368c2c8dfd71b84598f01074416e57cc3469d5b8ed2Jamie Gennis // make sure the client is not trying to dequeue more buffers 369c2c8dfd71b84598f01074416e57cc3469d5b8ed2Jamie Gennis // than allowed. 370c2c8dfd71b84598f01074416e57cc3469d5b8ed2Jamie Gennis const int avail = mBufferCount - (dequeuedCount+1); 371c2c8dfd71b84598f01074416e57cc3469d5b8ed2Jamie Gennis if (avail < (MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode))) { 372fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded " 373fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis "(dequeued=%d)", 374c2c8dfd71b84598f01074416e57cc3469d5b8ed2Jamie Gennis MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode), 375c2c8dfd71b84598f01074416e57cc3469d5b8ed2Jamie Gennis dequeuedCount); 376c2c8dfd71b84598f01074416e57cc3469d5b8ed2Jamie Gennis return -EBUSY; 377c2c8dfd71b84598f01074416e57cc3469d5b8ed2Jamie Gennis } 3788072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian } 3798072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 380b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian // we're in synchronous mode and didn't find a buffer, we need to wait 38129b5762efc359022168e5099c1d17925444d3147Mathias Agopian // for some buffers to be consumed 382b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian tryAgain = mSynchronousMode && (foundSync == INVALID_BUFFER_SLOT); 383b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian if (tryAgain) { 384b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mDequeueCondition.wait(mMutex); 385c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian } 386a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian } 387b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 3888072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian if (mSynchronousMode && found == INVALID_BUFFER_SLOT) { 3898072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // foundSync guaranteed to be != INVALID_BUFFER_SLOT 3908072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian found = foundSync; 391b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian } 392b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 393c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian if (found == INVALID_BUFFER_SLOT) { 3946ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis // This should not happen. 3956ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGE("dequeueBuffer: no available buffer slots"); 396c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian return -EBUSY; 397c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian } 398c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian 399c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian const int buf = found; 400c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian *outBuf = found; 401a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian 402a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian const bool useDefaultSize = !w && !h; 403a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian if (useDefaultSize) { 404a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian // use the default size 405a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian w = mDefaultWidth; 406a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian h = mDefaultHeight; 407a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian } 408a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian 409a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian const bool updateFormat = (format != 0); 410a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian if (!updateFormat) { 411a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian // keep the current (or default) format 412a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian format = mPixelFormat; 413a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian } 414a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian 415b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian // buffer is now in DEQUEUED (but can also be current at the same time, 416b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian // if we're in synchronous mode) 417b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mSlots[buf].mBufferState = BufferSlot::DEQUEUED; 418b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 419b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer); 420c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian if ((buffer == NULL) || 421c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian (uint32_t(buffer->width) != w) || 422c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian (uint32_t(buffer->height) != h) || 423c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian (uint32_t(buffer->format) != format) || 424c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian ((uint32_t(buffer->usage) & usage) != usage)) 425c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian { 426c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian usage |= GraphicBuffer::USAGE_HW_TEXTURE; 427d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian status_t error; 428c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian sp<GraphicBuffer> graphicBuffer( 429d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian mGraphicBufferAlloc->createGraphicBuffer( 430d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian w, h, format, usage, &error)); 431c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian if (graphicBuffer == 0) { 432fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer " 433fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis "failed"); 434d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian return error; 435c04f153353cdb0d291297d10452239f791d3fd2bMathias Agopian } 436a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian if (updateFormat) { 437a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian mPixelFormat = format; 438a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian } 4398ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis mSlots[buf].mGraphicBuffer = graphicBuffer; 440b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mSlots[buf].mRequestBufferCalled = false; 4418ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis if (mSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) { 4428ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis eglDestroyImageKHR(mSlots[buf].mEglDisplay, mSlots[buf].mEglImage); 4438ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis mSlots[buf].mEglImage = EGL_NO_IMAGE_KHR; 4448ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis mSlots[buf].mEglDisplay = EGL_NO_DISPLAY; 4458ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 446aaa3ecff4b49e0918c252e02b3aa18a3ad0d503dJamie Gennis if (mCurrentTexture == buf) { 447aaa3ecff4b49e0918c252e02b3aa18a3ad0d503dJamie Gennis // The current texture no longer references the buffer in this slot 448aaa3ecff4b49e0918c252e02b3aa18a3ad0d503dJamie Gennis // since we just allocated a new buffer. 449aaa3ecff4b49e0918c252e02b3aa18a3ad0d503dJamie Gennis mCurrentTexture = INVALID_BUFFER_SLOT; 450aaa3ecff4b49e0918c252e02b3aa18a3ad0d503dJamie Gennis } 4518072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION; 452a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian } 4536ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", buf, 4546ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis mSlots[buf].mGraphicBuffer->handle, returnFlags); 4558072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian return returnFlags; 4568ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 4578ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 458b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopianstatus_t SurfaceTexture::setSynchronousMode(bool enabled) { 4596ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("setSynchronousMode: enabled=%d", enabled); 460b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian Mutex::Autolock lock(mMutex); 4618072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 4627b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis if (mAbandoned) { 463fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("setSynchronousMode: SurfaceTexture has been abandoned!"); 4647b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis return NO_INIT; 4657b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis } 4667b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 4678072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian status_t err = OK; 46814a0e58074f2698829b6554f578e6762c377caa3Grace Kloba if (!mAllowSynchronousMode && enabled) 46914a0e58074f2698829b6554f578e6762c377caa3Grace Kloba return err; 47014a0e58074f2698829b6554f578e6762c377caa3Grace Kloba 4718072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian if (!enabled) { 4728072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // going to asynchronous mode, drain the queue 4738e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian err = drainQueueLocked(); 4748e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian if (err != NO_ERROR) 4758e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian return err; 4768072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian } 4778072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 478b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian if (mSynchronousMode != enabled) { 4798072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // - if we're going to asynchronous mode, the queue is guaranteed to be 4808072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // empty here 4818072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // - if the client set the number of buffers, we're guaranteed that 4828072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian // we have at least 3 (because we don't allow less) 483b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mSynchronousMode = enabled; 484b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mDequeueCondition.signal(); 485b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian } 4868072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian return err; 487b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian} 488b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 48997c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopianstatus_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp, 49097c602c5af5f3ffd69009bf496d86347b71a2b4cMathias Agopian uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) { 4916ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("queueBuffer: slot=%d time=%lld", buf, timestamp); 492cf46eb9817dfbfc020720d1e45b5c085252500fbMathias Agopian 493cf46eb9817dfbfc020720d1e45b5c085252500fbMathias Agopian sp<FrameAvailableListener> listener; 494cf46eb9817dfbfc020720d1e45b5c085252500fbMathias Agopian 495cf46eb9817dfbfc020720d1e45b5c085252500fbMathias Agopian { // scope for the lock 4968cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis Mutex::Autolock lock(mMutex); 4977b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis if (mAbandoned) { 498fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("queueBuffer: SurfaceTexture has been abandoned!"); 4997b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis return NO_INIT; 5007b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis } 5018cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis if (buf < 0 || buf >= mBufferCount) { 502fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d", 5038cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis mBufferCount, buf); 5048cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis return -EINVAL; 5058cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 506fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("queueBuffer: slot %d is not owned by the client " 507fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis "(state=%d)", buf, mSlots[buf].mBufferState); 5088cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis return -EINVAL; 5098cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis } else if (buf == mCurrentTexture) { 510fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("queueBuffer: slot %d is current!", buf); 5118cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis return -EINVAL; 5128cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis } else if (!mSlots[buf].mRequestBufferCalled) { 513fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("queueBuffer: slot %d was enqueued without requesting a " 5148cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis "buffer", buf); 5158cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis return -EINVAL; 5168cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis } 517cf46eb9817dfbfc020720d1e45b5c085252500fbMathias Agopian 5188cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis if (mSynchronousMode) { 5193d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis // In synchronous mode we queue all buffers in a FIFO. 520b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mQueue.push_back(buf); 5213d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis 5223d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis // Synchronous mode always signals that an additional frame should 5233d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis // be consumed. 5243d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis listener = mFrameAvailableListener; 525b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian } else { 5263d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis // In asynchronous mode we only keep the most recent buffer. 5278cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis if (mQueue.empty()) { 5288cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis mQueue.push_back(buf); 5293d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis 5303d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis // Asynchronous mode only signals that a frame should be 5313d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis // consumed if no previous frame was pending. If a frame were 5323d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis // pending then the consumer would have already been notified. 5333d8063b02e06020c8062addcc9ec49048d3bdb9aJamie Gennis listener = mFrameAvailableListener; 5348cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis } else { 5358cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis Fifo::iterator front(mQueue.begin()); 5368cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis // buffer currently queued is freed 5378cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis mSlots[*front].mBufferState = BufferSlot::FREE; 5388cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis // and we record the new buffer index in the queued list 5398cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis *front = buf; 5408cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis } 541b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian } 542b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 5438cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis mSlots[buf].mBufferState = BufferSlot::QUEUED; 5448cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis mSlots[buf].mCrop = mNextCrop; 5458cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis mSlots[buf].mTransform = mNextTransform; 5467734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian mSlots[buf].mScalingMode = mNextScalingMode; 5478cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis mSlots[buf].mTimestamp = timestamp; 548a929748ddb67cbece3337c7fda7877fdeb973aa4Sunita Nadampalli mFrameCounter++; 549a929748ddb67cbece3337c7fda7877fdeb973aa4Sunita Nadampalli mSlots[buf].mFrameNumber = mFrameCounter; 550a929748ddb67cbece3337c7fda7877fdeb973aa4Sunita Nadampalli 5518cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis mDequeueCondition.signal(); 5523902be629bd94de62db0039004d0b25556227cbfMathias Agopian 5533902be629bd94de62db0039004d0b25556227cbfMathias Agopian *outWidth = mDefaultWidth; 5543902be629bd94de62db0039004d0b25556227cbfMathias Agopian *outHeight = mDefaultHeight; 5553902be629bd94de62db0039004d0b25556227cbfMathias Agopian *outTransform = 0; 556cf46eb9817dfbfc020720d1e45b5c085252500fbMathias Agopian } // scope for the lock 557b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 558cf46eb9817dfbfc020720d1e45b5c085252500fbMathias Agopian // call back without lock held 559cf46eb9817dfbfc020720d1e45b5c085252500fbMathias Agopian if (listener != 0) { 560cf46eb9817dfbfc020720d1e45b5c085252500fbMathias Agopian listener->onFrameAvailable(); 561c4d4aeab52435c177ded6abdd578fec8191f0f5dJamie Gennis } 5628ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return OK; 5638ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 5648ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 5658ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennisvoid SurfaceTexture::cancelBuffer(int buf) { 5666ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("cancelBuffer: slot=%d", buf); 5678ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis Mutex::Autolock lock(mMutex); 5687b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 5697b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis if (mAbandoned) { 570fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGW("cancelBuffer: SurfaceTexture has been abandoned!"); 5717b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis return; 5727b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis } 5737b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 574b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian if (buf < 0 || buf >= mBufferCount) { 575fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d", 576b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mBufferCount, buf); 5778ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return; 578b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 579fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)", 580b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian buf, mSlots[buf].mBufferState); 5818ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return; 5828ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 583b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mSlots[buf].mBufferState = BufferSlot::FREE; 584a929748ddb67cbece3337c7fda7877fdeb973aa4Sunita Nadampalli mSlots[buf].mFrameNumber = 0; 585b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mDequeueCondition.signal(); 5868ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 5878ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 588f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatus_t SurfaceTexture::setCrop(const Rect& crop) { 5896ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("setCrop: crop=[%d,%d,%d,%d]", crop.left, crop.top, crop.right, 5906ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis crop.bottom); 5916ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis 5928ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis Mutex::Autolock lock(mMutex); 5937b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis if (mAbandoned) { 594fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("setCrop: SurfaceTexture has been abandoned!"); 5957b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis return NO_INIT; 5967b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis } 597f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis mNextCrop = crop; 5988ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return OK; 5998ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 6008ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 6018ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennisstatus_t SurfaceTexture::setTransform(uint32_t transform) { 6026ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("setTransform: xform=%#x", transform); 6038ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis Mutex::Autolock lock(mMutex); 6047b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis if (mAbandoned) { 605fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("setTransform: SurfaceTexture has been abandoned!"); 6067b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis return NO_INIT; 6077b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis } 608f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis mNextTransform = transform; 6098ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return OK; 6108ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 6118ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 6125bfc24515bb5c8ea7975f72d538df37753733a2fMathias Agopianstatus_t SurfaceTexture::connect(int api, 6135bfc24515bb5c8ea7975f72d538df37753733a2fMathias Agopian uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) { 6146ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("connect: api=%d", api); 615fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis Mutex::Autolock lock(mMutex); 6167b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 6177b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis if (mAbandoned) { 618fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("connect: SurfaceTexture has been abandoned!"); 6197b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis return NO_INIT; 6207b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis } 6217b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 622fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis int err = NO_ERROR; 623fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis switch (api) { 624fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis case NATIVE_WINDOW_API_EGL: 625fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis case NATIVE_WINDOW_API_CPU: 626fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis case NATIVE_WINDOW_API_MEDIA: 627fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis case NATIVE_WINDOW_API_CAMERA: 628fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis if (mConnectedApi != NO_CONNECTED_API) { 629fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("connect: already connected (cur=%d, req=%d)", 6308f9dbf9e13b927de2524116c30544f7dfbbbf56cMathias Agopian mConnectedApi, api); 631fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis err = -EINVAL; 632fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis } else { 633fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis mConnectedApi = api; 6345bfc24515bb5c8ea7975f72d538df37753733a2fMathias Agopian *outWidth = mDefaultWidth; 6355bfc24515bb5c8ea7975f72d538df37753733a2fMathias Agopian *outHeight = mDefaultHeight; 6365bfc24515bb5c8ea7975f72d538df37753733a2fMathias Agopian *outTransform = 0; 637fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis } 638fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis break; 639fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis default: 640fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis err = -EINVAL; 641fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis break; 642fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis } 643fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis return err; 644fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis} 645fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis 646fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennisstatus_t SurfaceTexture::disconnect(int api) { 6476ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("disconnect: api=%d", api); 648fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis Mutex::Autolock lock(mMutex); 6497b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 6507b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis if (mAbandoned) { 6518b8a004148f2e6337dbf02ef8046d800bf300e89Mathias Agopian // it is not really an error to disconnect after the surface 6528b8a004148f2e6337dbf02ef8046d800bf300e89Mathias Agopian // has been abandoned, it should just be a no-op. 6538b8a004148f2e6337dbf02ef8046d800bf300e89Mathias Agopian return NO_ERROR; 6547b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis } 6557b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 656fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis int err = NO_ERROR; 657fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis switch (api) { 658fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis case NATIVE_WINDOW_API_EGL: 659fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis case NATIVE_WINDOW_API_CPU: 660fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis case NATIVE_WINDOW_API_MEDIA: 661fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis case NATIVE_WINDOW_API_CAMERA: 662fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis if (mConnectedApi == api) { 6638e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian drainQueueAndFreeBuffersLocked(); 664fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis mConnectedApi = NO_CONNECTED_API; 66570e3f81d0fbc92394928c44fb0137787a8595665Mathias Agopian mNextCrop.makeInvalid(); 66670e3f81d0fbc92394928c44fb0137787a8595665Mathias Agopian mNextScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; 66770e3f81d0fbc92394928c44fb0137787a8595665Mathias Agopian mNextTransform = 0; 6688e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian mDequeueCondition.signal(); 669fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis } else { 670fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)", 6718f9dbf9e13b927de2524116c30544f7dfbbbf56cMathias Agopian mConnectedApi, api); 672fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis err = -EINVAL; 673fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis } 674fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis break; 675fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis default: 6766ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGE("disconnect: unknown API %d", api); 677fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis err = -EINVAL; 678fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis break; 679fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis } 680fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis return err; 681fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis} 682fe0a87b54654a1392650e7f1862df473287d8332Jamie Gennis 6837734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopianstatus_t SurfaceTexture::setScalingMode(int mode) { 6846ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("setScalingMode: mode=%d", mode); 6857734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian 6867734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian switch (mode) { 6877734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian case NATIVE_WINDOW_SCALING_MODE_FREEZE: 6887734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 6897734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian break; 6907734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian default: 6916ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGE("unknown scaling mode: %d", mode); 6927734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian return BAD_VALUE; 6937734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian } 6947734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian 6957734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian Mutex::Autolock lock(mMutex); 6967734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian mNextScalingMode = mode; 6977734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian return OK; 6987734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian} 6997734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian 7008ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennisstatus_t SurfaceTexture::updateTexImage() { 7016ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("updateTexImage"); 7028ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis Mutex::Autolock lock(mMutex); 7038ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 704e47498f8f258967ff62d070f08ff2dadd4ae2b56Mathias Agopian if (mAbandoned) { 705fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("calling updateTexImage() on an abandoned SurfaceTexture"); 7068e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian return NO_INIT; 707e47498f8f258967ff62d070f08ff2dadd4ae2b56Mathias Agopian } 708e47498f8f258967ff62d070f08ff2dadd4ae2b56Mathias Agopian 70950c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis // In asynchronous mode the list is guaranteed to be one buffer 71050c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis // deep, while in synchronous mode we use the oldest buffer. 711b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian if (!mQueue.empty()) { 712b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian Fifo::iterator front(mQueue.begin()); 71350c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis int buf = *front; 714b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 715f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis // Update the GL texture object. 716b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian EGLImageKHR image = mSlots[buf].mEglImage; 7178ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis if (image == EGL_NO_IMAGE_KHR) { 7188ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 719e47498f8f258967ff62d070f08ff2dadd4ae2b56Mathias Agopian if (mSlots[buf].mGraphicBuffer == 0) { 720fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("buffer at slot %d is null", buf); 7218e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian return BAD_VALUE; 722e47498f8f258967ff62d070f08ff2dadd4ae2b56Mathias Agopian } 723b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian image = createImage(dpy, mSlots[buf].mGraphicBuffer); 724b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mSlots[buf].mEglImage = image; 725b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mSlots[buf].mEglDisplay = dpy; 7263cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian if (image == EGL_NO_IMAGE_KHR) { 7273cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian // NOTE: if dpy was invalid, createImage() is guaranteed to 7283cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian // fail. so we'd end up here. 7293cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian return -EINVAL; 7303cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian } 7318ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 7320eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis 7330eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis GLint error; 7340eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis while ((error = glGetError()) != GL_NO_ERROR) { 735fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGW("updateTexImage: clearing GL error: %#04x", error); 7360eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis } 7377a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 738fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis glBindTexture(mTexTarget, mTexName); 739fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image); 7407a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7410eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis bool failed = false; 7420eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis while ((error = glGetError()) != GL_NO_ERROR) { 743fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("error binding external texture image %p (slot %d): %#04x", 744b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian image, buf, error); 7450eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis failed = true; 7460eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis } 7470eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis if (failed) { 7488ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return -EINVAL; 7498ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 7509a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 7516ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("updateTexImage: (slot=%d buf=%p) -> (slot=%d buf=%p)", mCurrentTexture, 7526ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis mCurrentTextureBuf != NULL ? mCurrentTextureBuf->handle : 0, buf, 7536ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis mSlots[buf].mGraphicBuffer->handle); 7546ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis 755b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian if (mCurrentTexture != INVALID_BUFFER_SLOT) { 75650c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis // The current buffer becomes FREE if it was still in the queued 757b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian // state. If it has already been given to the client 758b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian // (synchronous mode), then it stays in DEQUEUED state. 759b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian if (mSlots[mCurrentTexture].mBufferState == BufferSlot::QUEUED) 760b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mSlots[mCurrentTexture].mBufferState = BufferSlot::FREE; 761b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian } 762b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 7639a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis // Update the SurfaceTexture state. 764b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mCurrentTexture = buf; 765b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mCurrentTextureBuf = mSlots[buf].mGraphicBuffer; 7668cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis mCurrentCrop = mSlots[buf].mCrop; 7678cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis mCurrentTransform = mSlots[buf].mTransform; 7687734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian mCurrentScalingMode = mSlots[buf].mScalingMode; 7698cd5ba4b7f01d3a54a8f8bc6d1793aa5fc8e09efJamie Gennis mCurrentTimestamp = mSlots[buf].mTimestamp; 770736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis computeCurrentTransformMatrix(); 77150c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis 77250c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis // Now that we've passed the point at which failures can happen, 77350c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis // it's safe to remove the buffer from the front of the queue. 77450c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis mQueue.erase(front); 775b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mDequeueCondition.signal(); 7767a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian } else { 7777a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // We always bind the texture even if we don't update its contents. 778fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis glBindTexture(mTexTarget, mTexName); 7798ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 78050c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis 7818ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return OK; 7828ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 7838ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 7847a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopianbool SurfaceTexture::isExternalFormat(uint32_t format) 7857a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian{ 7867a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian switch (format) { 7877a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // supported YUV formats 7887a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YV12: 7897a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Legacy/deprecated YUV formats 7907a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_SP: 7917a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCrCb_420_SP: 7927a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_I: 7937a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 7947a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian } 7957a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7967a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Any OEM format needs to be considered 7977a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian if (format>=0x100 && format<=0x1FF) 7987a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 7997a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 8007a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return false; 8017a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 8027a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 8037a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias AgopianGLenum SurfaceTexture::getCurrentTextureTarget() const { 804fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis return mTexTarget; 8057a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 8067a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 807f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisvoid SurfaceTexture::getTransformMatrix(float mtx[16]) { 808f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis Mutex::Autolock lock(mMutex); 809736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix)); 810736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis} 811736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis 812736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennisvoid SurfaceTexture::computeCurrentTransformMatrix() { 8136ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("computeCurrentTransformMatrix"); 814f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 815a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float xform[16]; 816a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 817a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = mtxIdentity[i]; 818a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 819a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) { 820a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 821a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipH); 822a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 823a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 824a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 825a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 826a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) { 827a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 828a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipV); 829a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 830a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 831a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 832a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 833a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 834a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 835a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxRot90); 836a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 837a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 838a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 839f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis } 840f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 841f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis sp<GraphicBuffer>& buf(mSlots[mCurrentTexture].mGraphicBuffer); 842a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float tx, ty, sx, sy; 843a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (!mCurrentCrop.isEmpty()) { 844d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // In order to prevent bilinear sampling at the of the crop rectangle we 845d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // may need to shrink it by 2 texels in each direction. Normally this 846d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // would just need to take 1/2 a texel off each end, but because the 847d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // chroma channels will likely be subsampled we need to chop off a whole 848d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // texel. This will cause artifacts if someone does nearest sampling 849d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // with 1:1 pixel:texel ratio, but it's impossible to simultaneously 850d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // accomodate the bilinear and nearest sampling uses. 851d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // 852d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // If nearest sampling turns out to be a desirable usage of these 853d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // textures then we could add the ability to switch a SurfaceTexture to 854d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // nearest-mode. Preferably, however, the image producers (video 855d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // decoder, camera, etc.) would simply not use a crop rectangle (or at 856d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // least not tell the framework about it) so that the GPU can do the 857d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // correct edge behavior. 858d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis int xshrink = 0, yshrink = 0; 859d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis if (mCurrentCrop.left > 0) { 860d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis tx = float(mCurrentCrop.left + 1) / float(buf->getWidth()); 861d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis xshrink++; 862d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } else { 863d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis tx = 0.0f; 864d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 865a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian if (mCurrentCrop.right < int32_t(buf->getWidth())) { 866d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis xshrink++; 867d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 868a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian if (mCurrentCrop.bottom < int32_t(buf->getHeight())) { 869d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis ty = (float(buf->getHeight() - mCurrentCrop.bottom) + 1.0f) / 870d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis float(buf->getHeight()); 871d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis yshrink++; 872d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } else { 873d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis ty = 0.0f; 874d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 875d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis if (mCurrentCrop.top > 0) { 876d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis yshrink++; 877d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 878d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis sx = float(mCurrentCrop.width() - xshrink) / float(buf->getWidth()); 879d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis sy = float(mCurrentCrop.height() - yshrink) / float(buf->getHeight()); 880a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } else { 881a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis tx = 0.0f; 882a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis ty = 0.0f; 883a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis sx = 1.0f; 884a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis sy = 1.0f; 885a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 886f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis float crop[16] = { 887a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis sx, 0, 0, 0, 888a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis 0, sy, 0, 0, 889f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 890d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis tx, ty, 0, 1, 891f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis }; 892f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 893a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float mtxBeforeFlipV[16]; 894a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(mtxBeforeFlipV, crop, xform); 895a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis 896a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // SurfaceFlinger expects the top of its window textures to be at a Y 897a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // coordinate of 0, so SurfaceTexture must behave the same way. We don't 898a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // want to expose this to applications, however, so we must add an 899a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // additional vertical flip to the transform after all the other transforms. 900736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis mtxMul(mCurrentTransformMatrix, mtxFlipV, mtxBeforeFlipV); 901f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 902f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 9031d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvalansecs_t SurfaceTexture::getTimestamp() { 9046ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("getTimestamp"); 9051d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala Mutex::Autolock lock(mMutex); 9061d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala return mCurrentTimestamp; 9071d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala} 9081d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala 909c4d4aeab52435c177ded6abdd578fec8191f0f5dJamie Gennisvoid SurfaceTexture::setFrameAvailableListener( 910292a31a4c2ae2f6faf134e8e4a726583017dad06Pannag Sanketi const sp<FrameAvailableListener>& listener) { 9116ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("setFrameAvailableListener"); 912c4d4aeab52435c177ded6abdd578fec8191f0f5dJamie Gennis Mutex::Autolock lock(mMutex); 913292a31a4c2ae2f6faf134e8e4a726583017dad06Pannag Sanketi mFrameAvailableListener = listener; 914c4d4aeab52435c177ded6abdd578fec8191f0f5dJamie Gennis} 915c4d4aeab52435c177ded6abdd578fec8191f0f5dJamie Gennis 9168e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopianvoid SurfaceTexture::freeBufferLocked(int i) { 9178e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian mSlots[i].mGraphicBuffer = 0; 9188e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian mSlots[i].mBufferState = BufferSlot::FREE; 919a929748ddb67cbece3337c7fda7877fdeb973aa4Sunita Nadampalli mSlots[i].mFrameNumber = 0; 9208e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian if (mSlots[i].mEglImage != EGL_NO_IMAGE_KHR) { 9218e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian eglDestroyImageKHR(mSlots[i].mEglDisplay, mSlots[i].mEglImage); 9228e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian mSlots[i].mEglImage = EGL_NO_IMAGE_KHR; 9238e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian mSlots[i].mEglDisplay = EGL_NO_DISPLAY; 9248e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian } 9258e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian} 9268e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian 927ef51b992192adf4fc432686ab346f5fc7a13bc95Mathias Agopianvoid SurfaceTexture::freeAllBuffersLocked() { 928ef51b992192adf4fc432686ab346f5fc7a13bc95Mathias Agopian LOGW_IF(!mQueue.isEmpty(), 929ef51b992192adf4fc432686ab346f5fc7a13bc95Mathias Agopian "freeAllBuffersLocked called but mQueue is not empty"); 93029b5762efc359022168e5099c1d17925444d3147Mathias Agopian mCurrentTexture = INVALID_BUFFER_SLOT; 9318ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 9328e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian freeBufferLocked(i); 9338e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian } 9348e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian} 9358e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian 9368e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopianvoid SurfaceTexture::freeAllBuffersExceptHeadLocked() { 9378e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian LOGW_IF(!mQueue.isEmpty(), 9388e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian "freeAllBuffersExceptCurrentLocked called but mQueue is not empty"); 9398e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian int head = -1; 9408e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian if (!mQueue.empty()) { 9418e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian Fifo::iterator front(mQueue.begin()); 9428e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian head = *front; 9438e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian } 94429b5762efc359022168e5099c1d17925444d3147Mathias Agopian mCurrentTexture = INVALID_BUFFER_SLOT; 9458e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 9468e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian if (i != head) { 9478e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian freeBufferLocked(i); 9488ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 9498ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 9508ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 9518ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 9528e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopianstatus_t SurfaceTexture::drainQueueLocked() { 9532560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian while (mSynchronousMode && !mQueue.isEmpty()) { 9542560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian mDequeueCondition.wait(mMutex); 9558e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian if (mAbandoned) { 956fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("drainQueueLocked: SurfaceTexture has been abandoned!"); 9578e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian return NO_INIT; 9588e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian } 9598e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian if (mConnectedApi == NO_CONNECTED_API) { 960fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("drainQueueLocked: SurfaceTexture is not connected!"); 9618e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian return NO_INIT; 9628e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian } 9632560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian } 9648e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian return NO_ERROR; 9658e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian} 9668e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian 9678e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopianstatus_t SurfaceTexture::drainQueueAndFreeBuffersLocked() { 9688e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian status_t err = drainQueueLocked(); 9698e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian if (err == NO_ERROR) { 9708e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian if (mSynchronousMode) { 9718e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian freeAllBuffersLocked(); 9728e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian } else { 9738e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian freeAllBuffersExceptHeadLocked(); 9748e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian } 9758e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian } 9768e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian return err; 9772560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian} 9782560d14ce8e38984032d999e3fdf8da9a47baf3cMathias Agopian 9798ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie GennisEGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy, 9808ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis const sp<GraphicBuffer>& graphicBuffer) { 9818ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLClientBuffer cbuf = (EGLClientBuffer)graphicBuffer->getNativeBuffer(); 9828ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLint attrs[] = { 9838ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 9848ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_NONE, 9858ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis }; 9868ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, 9878ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs); 9883cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian if (image == EGL_NO_IMAGE_KHR) { 9893cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian EGLint error = eglGetError(); 990fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("error creating EGLImage: %#x", error); 9918ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 9928ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return image; 9938ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 9948ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 9957a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopiansp<GraphicBuffer> SurfaceTexture::getCurrentBuffer() const { 9967a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 9977a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTextureBuf; 9987a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 9997a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 10007a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias AgopianRect SurfaceTexture::getCurrentCrop() const { 10017a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 10027a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentCrop; 10037a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 10047a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 10057a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopianuint32_t SurfaceTexture::getCurrentTransform() const { 10067a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 10077a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTransform; 10087a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 10097a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 10107734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopianuint32_t SurfaceTexture::getCurrentScalingMode() const { 10117734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian Mutex::Autolock lock(mMutex); 10127734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian return mCurrentScalingMode; 10137734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian} 10147734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian 101559769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennisbool SurfaceTexture::isSynchronousMode() const { 101659769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis Mutex::Autolock lock(mMutex); 101759769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis return mSynchronousMode; 101859769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis} 101959769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis 1020eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopianint SurfaceTexture::query(int what, int* outValue) 1021eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian{ 1022eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian Mutex::Autolock lock(mMutex); 10237b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 10247b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis if (mAbandoned) { 1025fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("query: SurfaceTexture has been abandoned!"); 10267b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis return NO_INIT; 10277b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis } 10287b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 1029eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian int value; 1030eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian switch (what) { 1031eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian case NATIVE_WINDOW_WIDTH: 1032eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian value = mDefaultWidth; 1033eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian break; 1034eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian case NATIVE_WINDOW_HEIGHT: 1035eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian value = mDefaultHeight; 1036eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian break; 1037eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian case NATIVE_WINDOW_FORMAT: 1038eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian value = mPixelFormat; 1039eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian break; 1040eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 1041eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian value = mSynchronousMode ? 1042eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian (MIN_UNDEQUEUED_BUFFERS-1) : MIN_UNDEQUEUED_BUFFERS; 1043eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian break; 1044eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian default: 1045eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian return BAD_VALUE; 1046eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian } 1047eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian outValue[0] = value; 1048eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian return NO_ERROR; 1049eafabcdc1639fb96062d9e3c39b0ae27b0238ae1Mathias Agopian} 10507a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 10517b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennisvoid SurfaceTexture::abandon() { 10527b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis Mutex::Autolock lock(mMutex); 10538e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian mQueue.clear(); 10547b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis mAbandoned = true; 105597a9884edcc6fbb311386ecfcd6e3045437f0df0Mathias Agopian mCurrentTextureBuf.clear(); 10568e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian freeAllBuffersLocked(); 10577b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis mDequeueCondition.signal(); 10587b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis} 10597b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 1060fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennisvoid SurfaceTexture::setName(const String8& name) { 1061fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis mName = name; 1062fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis} 1063fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis 106468c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopianvoid SurfaceTexture::dump(String8& result) const 106568c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian{ 106668c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian char buffer[1024]; 106768c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian dump(result, "", buffer, 1024); 106868c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian} 106968c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 107068c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopianvoid SurfaceTexture::dump(String8& result, const char* prefix, 107168c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian char* buffer, size_t SIZE) const 107268c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian{ 107368c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian Mutex::Autolock _l(mMutex); 107468c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian snprintf(buffer, SIZE, 107568c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian "%smBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], " 107668c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian "mPixelFormat=%d, mTexName=%d\n", 1077fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis prefix, mBufferCount, mSynchronousMode, mDefaultWidth, 1078fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis mDefaultHeight, mPixelFormat, mTexName); 107968c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian result.append(buffer); 108068c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 108168c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian String8 fifo; 108268c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian int fifoSize = 0; 108368c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian Fifo::const_iterator i(mQueue.begin()); 108468c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian while (i != mQueue.end()) { 108568c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian snprintf(buffer, SIZE, "%02d ", *i++); 108668c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian fifoSize++; 108768c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian fifo.append(buffer); 108868c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian } 108968c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 109068c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian snprintf(buffer, SIZE, 10911f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis "%scurrent: {crop=[%d,%d,%d,%d], transform=0x%02x, current=%d}\n" 109268c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian "%snext : {crop=[%d,%d,%d,%d], transform=0x%02x, FIFO(%d)={%s}}\n" 109368c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian , 109468c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian prefix, mCurrentCrop.left, 109568c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom, 10961f8e09f40d16ae377164d86e91385ad3d8e78e82Jamie Gennis mCurrentTransform, mCurrentTexture, 1097fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis prefix, mNextCrop.left, mNextCrop.top, mNextCrop.right, 1098fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis mNextCrop.bottom, mNextTransform, fifoSize, fifo.string() 109968c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian ); 110068c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian result.append(buffer); 110168c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 110268c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian struct { 110368c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian const char * operator()(int state) const { 110468c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian switch (state) { 110568c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian case BufferSlot::DEQUEUED: return "DEQUEUED"; 110668c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian case BufferSlot::QUEUED: return "QUEUED"; 110768c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian case BufferSlot::FREE: return "FREE"; 110868c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian default: return "Unknown"; 110968c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian } 111068c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian } 111168c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian } stateName; 111268c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 111368c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian for (int i=0 ; i<mBufferCount ; i++) { 111468c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian const BufferSlot& slot(mSlots[i]); 111568c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian snprintf(buffer, SIZE, 1116ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian "%s%s[%02d] " 1117ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian "state=%-8s, crop=[%d,%d,%d,%d], " 11182db6f0a40b7f4d903f546e94af762f141953ebb2Mathias Agopian "transform=0x%02x, timestamp=%lld", 1119ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian prefix, (i==mCurrentTexture)?">":" ", i, 1120ad795baecccf239621cbffa0249c8e855296cae6Mathias Agopian stateName(slot.mBufferState), 1121fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis slot.mCrop.left, slot.mCrop.top, slot.mCrop.right, 1122fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis slot.mCrop.bottom, slot.mTransform, slot.mTimestamp 112368c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian ); 112468c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian result.append(buffer); 11252db6f0a40b7f4d903f546e94af762f141953ebb2Mathias Agopian 11262db6f0a40b7f4d903f546e94af762f141953ebb2Mathias Agopian const sp<GraphicBuffer>& buf(slot.mGraphicBuffer); 11272db6f0a40b7f4d903f546e94af762f141953ebb2Mathias Agopian if (buf != NULL) { 11282db6f0a40b7f4d903f546e94af762f141953ebb2Mathias Agopian snprintf(buffer, SIZE, 11292db6f0a40b7f4d903f546e94af762f141953ebb2Mathias Agopian ", %p [%4ux%4u:%4u,%3X]", 1130fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis buf->handle, buf->width, buf->height, buf->stride, 1131fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis buf->format); 11322db6f0a40b7f4d903f546e94af762f141953ebb2Mathias Agopian result.append(buffer); 11332db6f0a40b7f4d903f546e94af762f141953ebb2Mathias Agopian } 11342db6f0a40b7f4d903f546e94af762f141953ebb2Mathias Agopian result.append("\n"); 113568c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian } 113668c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian} 113768c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 1138f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]) { 1139f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3]; 1140f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3]; 1141f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3]; 1142f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3]; 1143f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1144f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7]; 1145f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7]; 1146f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7]; 1147f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7]; 1148f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1149f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11]; 1150f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11]; 1151f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11]; 1152f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11]; 1153f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1154f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15]; 1155f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15]; 1156f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15]; 1157f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15]; 1158f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 1159f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 11608ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis}; // namespace android 1161