Home | History | Annotate | Download | only in gui
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "SurfaceTexture"
     18 //#define LOG_NDEBUG 0
     19 
     20 #define GL_GLEXT_PROTOTYPES
     21 #define EGL_EGLEXT_PROTOTYPES
     22 
     23 #include <EGL/egl.h>
     24 #include <EGL/eglext.h>
     25 #include <GLES2/gl2.h>
     26 #include <GLES2/gl2ext.h>
     27 
     28 #include <gui/SurfaceTexture.h>
     29 
     30 #include <hardware/hardware.h>
     31 
     32 #include <surfaceflinger/ISurfaceComposer.h>
     33 #include <surfaceflinger/SurfaceComposerClient.h>
     34 #include <surfaceflinger/IGraphicBufferAlloc.h>
     35 
     36 #include <utils/Log.h>
     37 #include <utils/String8.h>
     38 
     39 
     40 #define ALLOW_DEQUEUE_CURRENT_BUFFER    false
     41 
     42 // Macros for including the SurfaceTexture name in log messages
     43 #define ST_LOGV(x, ...) LOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
     44 #define ST_LOGD(x, ...) LOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
     45 #define ST_LOGI(x, ...) LOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
     46 #define ST_LOGW(x, ...) LOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
     47 #define ST_LOGE(x, ...) LOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
     48 
     49 namespace android {
     50 
     51 // Transform matrices
     52 static float mtxIdentity[16] = {
     53     1, 0, 0, 0,
     54     0, 1, 0, 0,
     55     0, 0, 1, 0,
     56     0, 0, 0, 1,
     57 };
     58 static float mtxFlipH[16] = {
     59     -1, 0, 0, 0,
     60     0, 1, 0, 0,
     61     0, 0, 1, 0,
     62     1, 0, 0, 1,
     63 };
     64 static float mtxFlipV[16] = {
     65     1, 0, 0, 0,
     66     0, -1, 0, 0,
     67     0, 0, 1, 0,
     68     0, 1, 0, 1,
     69 };
     70 static float mtxRot90[16] = {
     71     0, 1, 0, 0,
     72     -1, 0, 0, 0,
     73     0, 0, 1, 0,
     74     1, 0, 0, 1,
     75 };
     76 static float mtxRot180[16] = {
     77     -1, 0, 0, 0,
     78     0, -1, 0, 0,
     79     0, 0, 1, 0,
     80     1, 1, 0, 1,
     81 };
     82 static float mtxRot270[16] = {
     83     0, -1, 0, 0,
     84     1, 0, 0, 0,
     85     0, 0, 1, 0,
     86     0, 1, 0, 1,
     87 };
     88 
     89 static void mtxMul(float out[16], const float a[16], const float b[16]);
     90 
     91 // Get an ID that's unique within this process.
     92 static int32_t createProcessUniqueId() {
     93     static volatile int32_t globalCounter = 0;
     94     return android_atomic_inc(&globalCounter);
     95 }
     96 
     97 SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
     98         GLenum texTarget) :
     99     mDefaultWidth(1),
    100     mDefaultHeight(1),
    101     mPixelFormat(PIXEL_FORMAT_RGBA_8888),
    102     mBufferCount(MIN_ASYNC_BUFFER_SLOTS),
    103     mClientBufferCount(0),
    104     mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS),
    105     mCurrentTexture(INVALID_BUFFER_SLOT),
    106     mCurrentTransform(0),
    107     mCurrentTimestamp(0),
    108     mNextTransform(0),
    109     mNextScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
    110     mTexName(tex),
    111     mSynchronousMode(false),
    112     mAllowSynchronousMode(allowSynchronousMode),
    113     mConnectedApi(NO_CONNECTED_API),
    114     mAbandoned(false),
    115     mTexTarget(texTarget) {
    116     // Choose a name using the PID and a process-unique ID.
    117     mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
    118 
    119     ST_LOGV("SurfaceTexture::SurfaceTexture");
    120     sp<ISurfaceComposer> composer(ComposerService::getComposerService());
    121     mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
    122     mNextCrop.makeInvalid();
    123     memcpy(mCurrentTransformMatrix, mtxIdentity,
    124             sizeof(mCurrentTransformMatrix));
    125 }
    126 
    127 SurfaceTexture::~SurfaceTexture() {
    128     ST_LOGV("SurfaceTexture::~SurfaceTexture");
    129     freeAllBuffersLocked();
    130 }
    131 
    132 status_t SurfaceTexture::setBufferCountServerLocked(int bufferCount) {
    133     if (bufferCount > NUM_BUFFER_SLOTS)
    134         return BAD_VALUE;
    135 
    136     // special-case, nothing to do
    137     if (bufferCount == mBufferCount)
    138         return OK;
    139 
    140     if (!mClientBufferCount &&
    141         bufferCount >= mBufferCount) {
    142         // easy, we just have more buffers
    143         mBufferCount = bufferCount;
    144         mServerBufferCount = bufferCount;
    145         mDequeueCondition.signal();
    146     } else {
    147         // we're here because we're either
    148         // - reducing the number of available buffers
    149         // - or there is a client-buffer-count in effect
    150 
    151         // less than 2 buffers is never allowed
    152         if (bufferCount < 2)
    153             return BAD_VALUE;
    154 
    155         // when there is non client-buffer-count in effect, the client is not
    156         // allowed to dequeue more than one buffer at a time,
    157         // so the next time they dequeue a buffer, we know that they don't
    158         // own one. the actual resizing will happen during the next
    159         // dequeueBuffer.
    160 
    161         mServerBufferCount = bufferCount;
    162     }
    163     return OK;
    164 }
    165 
    166 status_t SurfaceTexture::setBufferCountServer(int bufferCount) {
    167     Mutex::Autolock lock(mMutex);
    168     return setBufferCountServerLocked(bufferCount);
    169 }
    170 
    171 status_t SurfaceTexture::setBufferCount(int bufferCount) {
    172     ST_LOGV("SurfaceTexture::setBufferCount");
    173     Mutex::Autolock lock(mMutex);
    174 
    175     if (mAbandoned) {
    176         ST_LOGE("setBufferCount: SurfaceTexture has been abandoned!");
    177         return NO_INIT;
    178     }
    179     if (bufferCount > NUM_BUFFER_SLOTS) {
    180         ST_LOGE("setBufferCount: bufferCount larger than slots available");
    181         return BAD_VALUE;
    182     }
    183 
    184     // Error out if the user has dequeued buffers
    185     for (int i=0 ; i<mBufferCount ; i++) {
    186         if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) {
    187             ST_LOGE("setBufferCount: client owns some buffers");
    188             return -EINVAL;
    189         }
    190     }
    191 
    192     const int minBufferSlots = mSynchronousMode ?
    193             MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
    194     if (bufferCount == 0) {
    195         mClientBufferCount = 0;
    196         bufferCount = (mServerBufferCount >= minBufferSlots) ?
    197                 mServerBufferCount : minBufferSlots;
    198         return setBufferCountServerLocked(bufferCount);
    199     }
    200 
    201     if (bufferCount < minBufferSlots) {
    202         ST_LOGE("setBufferCount: requested buffer count (%d) is less than "
    203                 "minimum (%d)", bufferCount, minBufferSlots);
    204         return BAD_VALUE;
    205     }
    206 
    207     // here we're guaranteed that the client doesn't have dequeued buffers
    208     // and will release all of its buffer references.
    209     freeAllBuffersLocked();
    210     mBufferCount = bufferCount;
    211     mClientBufferCount = bufferCount;
    212     mCurrentTexture = INVALID_BUFFER_SLOT;
    213     mQueue.clear();
    214     mDequeueCondition.signal();
    215     return OK;
    216 }
    217 
    218 status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h)
    219 {
    220     if (!w || !h) {
    221         ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)",
    222                 w, h);
    223         return BAD_VALUE;
    224     }
    225 
    226     Mutex::Autolock lock(mMutex);
    227     mDefaultWidth = w;
    228     mDefaultHeight = h;
    229     return OK;
    230 }
    231 
    232 status_t SurfaceTexture::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
    233     ST_LOGV("SurfaceTexture::requestBuffer");
    234     Mutex::Autolock lock(mMutex);
    235     if (mAbandoned) {
    236         ST_LOGE("requestBuffer: SurfaceTexture has been abandoned!");
    237         return NO_INIT;
    238     }
    239     if (slot < 0 || mBufferCount <= slot) {
    240         ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d",
    241                 mBufferCount, slot);
    242         return BAD_VALUE;
    243     }
    244     mSlots[slot].mRequestBufferCalled = true;
    245     *buf = mSlots[slot].mGraphicBuffer;
    246     return NO_ERROR;
    247 }
    248 
    249 status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
    250         uint32_t format, uint32_t usage) {
    251     ST_LOGV("SurfaceTexture::dequeueBuffer");
    252 
    253     if ((w && !h) || (!w && h)) {
    254         ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);
    255         return BAD_VALUE;
    256     }
    257 
    258     Mutex::Autolock lock(mMutex);
    259 
    260     status_t returnFlags(OK);
    261 
    262     int found, foundSync;
    263     int dequeuedCount = 0;
    264     bool tryAgain = true;
    265     while (tryAgain) {
    266         if (mAbandoned) {
    267             ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
    268             return NO_INIT;
    269         }
    270 
    271         // We need to wait for the FIFO to drain if the number of buffer
    272         // needs to change.
    273         //
    274         // The condition "number of buffers needs to change" is true if
    275         // - the client doesn't care about how many buffers there are
    276         // - AND the actual number of buffer is different from what was
    277         //   set in the last setBufferCountServer()
    278         //                         - OR -
    279         //   setBufferCountServer() was set to a value incompatible with
    280         //   the synchronization mode (for instance because the sync mode
    281         //   changed since)
    282         //
    283         // As long as this condition is true AND the FIFO is not empty, we
    284         // wait on mDequeueCondition.
    285 
    286         const int minBufferCountNeeded = mSynchronousMode ?
    287                 MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
    288 
    289         const bool numberOfBuffersNeedsToChange = !mClientBufferCount &&
    290                 ((mServerBufferCount != mBufferCount) ||
    291                         (mServerBufferCount < minBufferCountNeeded));
    292 
    293         if (!mQueue.isEmpty() && numberOfBuffersNeedsToChange) {
    294             // wait for the FIFO to drain
    295             mDequeueCondition.wait(mMutex);
    296             // NOTE: we continue here because we need to reevaluate our
    297             // whole state (eg: we could be abandoned or disconnected)
    298             continue;
    299         }
    300 
    301         if (numberOfBuffersNeedsToChange) {
    302             // here we're guaranteed that mQueue is empty
    303             freeAllBuffersLocked();
    304             mBufferCount = mServerBufferCount;
    305             if (mBufferCount < minBufferCountNeeded)
    306                 mBufferCount = minBufferCountNeeded;
    307             mCurrentTexture = INVALID_BUFFER_SLOT;
    308             returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
    309         }
    310 
    311         // look for a free buffer to give to the client
    312         found = INVALID_BUFFER_SLOT;
    313         foundSync = INVALID_BUFFER_SLOT;
    314         dequeuedCount = 0;
    315         for (int i = 0; i < mBufferCount; i++) {
    316             const int state = mSlots[i].mBufferState;
    317             if (state == BufferSlot::DEQUEUED) {
    318                 dequeuedCount++;
    319             }
    320 
    321             // if buffer is FREE it CANNOT be current
    322             LOGW_IF((state == BufferSlot::FREE) && (mCurrentTexture==i),
    323                     "dequeueBuffer: buffer %d is both FREE and current!", i);
    324 
    325             if (ALLOW_DEQUEUE_CURRENT_BUFFER) {
    326                 if (state == BufferSlot::FREE || i == mCurrentTexture) {
    327                     foundSync = i;
    328                     if (i != mCurrentTexture) {
    329                         found = i;
    330                         break;
    331                     }
    332                 }
    333             } else {
    334                 if (state == BufferSlot::FREE) {
    335                     foundSync = i;
    336                     found = i;
    337                     break;
    338                 }
    339             }
    340         }
    341 
    342         // clients are not allowed to dequeue more than one buffer
    343         // if they didn't set a buffer count.
    344         if (!mClientBufferCount && dequeuedCount) {
    345             return -EINVAL;
    346         }
    347 
    348         // See whether a buffer has been queued since the last setBufferCount so
    349         // we know whether to perform the MIN_UNDEQUEUED_BUFFERS check below.
    350         bool bufferHasBeenQueued = mCurrentTexture != INVALID_BUFFER_SLOT;
    351         if (bufferHasBeenQueued) {
    352             // make sure the client is not trying to dequeue more buffers
    353             // than allowed.
    354             const int avail = mBufferCount - (dequeuedCount+1);
    355             if (avail < (MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode))) {
    356                 ST_LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded "
    357                         "(dequeued=%d)",
    358                         MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode),
    359                         dequeuedCount);
    360                 return -EBUSY;
    361             }
    362         }
    363 
    364         // we're in synchronous mode and didn't find a buffer, we need to wait
    365         // for some buffers to be consumed
    366         tryAgain = mSynchronousMode && (foundSync == INVALID_BUFFER_SLOT);
    367         if (tryAgain) {
    368             mDequeueCondition.wait(mMutex);
    369         }
    370     }
    371 
    372     if (mSynchronousMode && found == INVALID_BUFFER_SLOT) {
    373         // foundSync guaranteed to be != INVALID_BUFFER_SLOT
    374         found = foundSync;
    375     }
    376 
    377     if (found == INVALID_BUFFER_SLOT) {
    378         return -EBUSY;
    379     }
    380 
    381     const int buf = found;
    382     *outBuf = found;
    383 
    384     const bool useDefaultSize = !w && !h;
    385     if (useDefaultSize) {
    386         // use the default size
    387         w = mDefaultWidth;
    388         h = mDefaultHeight;
    389     }
    390 
    391     const bool updateFormat = (format != 0);
    392     if (!updateFormat) {
    393         // keep the current (or default) format
    394         format = mPixelFormat;
    395     }
    396 
    397     // buffer is now in DEQUEUED (but can also be current at the same time,
    398     // if we're in synchronous mode)
    399     mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
    400 
    401     const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
    402     if ((buffer == NULL) ||
    403         (uint32_t(buffer->width)  != w) ||
    404         (uint32_t(buffer->height) != h) ||
    405         (uint32_t(buffer->format) != format) ||
    406         ((uint32_t(buffer->usage) & usage) != usage))
    407     {
    408         usage |= GraphicBuffer::USAGE_HW_TEXTURE;
    409         status_t error;
    410         sp<GraphicBuffer> graphicBuffer(
    411                 mGraphicBufferAlloc->createGraphicBuffer(
    412                         w, h, format, usage, &error));
    413         if (graphicBuffer == 0) {
    414             ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer "
    415                     "failed");
    416             return error;
    417         }
    418         if (updateFormat) {
    419             mPixelFormat = format;
    420         }
    421         mSlots[buf].mGraphicBuffer = graphicBuffer;
    422         mSlots[buf].mRequestBufferCalled = false;
    423         if (mSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) {
    424             eglDestroyImageKHR(mSlots[buf].mEglDisplay, mSlots[buf].mEglImage);
    425             mSlots[buf].mEglImage = EGL_NO_IMAGE_KHR;
    426             mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
    427         }
    428         returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
    429     }
    430     return returnFlags;
    431 }
    432 
    433 status_t SurfaceTexture::setSynchronousMode(bool enabled) {
    434     Mutex::Autolock lock(mMutex);
    435 
    436     if (mAbandoned) {
    437         ST_LOGE("setSynchronousMode: SurfaceTexture has been abandoned!");
    438         return NO_INIT;
    439     }
    440 
    441     status_t err = OK;
    442     if (!mAllowSynchronousMode && enabled)
    443         return err;
    444 
    445     if (!enabled) {
    446         // going to asynchronous mode, drain the queue
    447         err = drainQueueLocked();
    448         if (err != NO_ERROR)
    449             return err;
    450     }
    451 
    452     if (mSynchronousMode != enabled) {
    453         // - if we're going to asynchronous mode, the queue is guaranteed to be
    454         // empty here
    455         // - if the client set the number of buffers, we're guaranteed that
    456         // we have at least 3 (because we don't allow less)
    457         mSynchronousMode = enabled;
    458         mDequeueCondition.signal();
    459     }
    460     return err;
    461 }
    462 
    463 status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp,
    464         uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
    465     ST_LOGV("SurfaceTexture::queueBuffer");
    466 
    467     sp<FrameAvailableListener> listener;
    468 
    469     { // scope for the lock
    470         Mutex::Autolock lock(mMutex);
    471         if (mAbandoned) {
    472             ST_LOGE("queueBuffer: SurfaceTexture has been abandoned!");
    473             return NO_INIT;
    474         }
    475         if (buf < 0 || buf >= mBufferCount) {
    476             ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d",
    477                     mBufferCount, buf);
    478             return -EINVAL;
    479         } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
    480             ST_LOGE("queueBuffer: slot %d is not owned by the client "
    481                     "(state=%d)", buf, mSlots[buf].mBufferState);
    482             return -EINVAL;
    483         } else if (buf == mCurrentTexture) {
    484             ST_LOGE("queueBuffer: slot %d is current!", buf);
    485             return -EINVAL;
    486         } else if (!mSlots[buf].mRequestBufferCalled) {
    487             ST_LOGE("queueBuffer: slot %d was enqueued without requesting a "
    488                     "buffer", buf);
    489             return -EINVAL;
    490         }
    491 
    492         if (mSynchronousMode) {
    493             // In synchronous mode we queue all buffers in a FIFO.
    494             mQueue.push_back(buf);
    495 
    496             // Synchronous mode always signals that an additional frame should
    497             // be consumed.
    498             listener = mFrameAvailableListener;
    499         } else {
    500             // In asynchronous mode we only keep the most recent buffer.
    501             if (mQueue.empty()) {
    502                 mQueue.push_back(buf);
    503 
    504                 // Asynchronous mode only signals that a frame should be
    505                 // consumed if no previous frame was pending. If a frame were
    506                 // pending then the consumer would have already been notified.
    507                 listener = mFrameAvailableListener;
    508             } else {
    509                 Fifo::iterator front(mQueue.begin());
    510                 // buffer currently queued is freed
    511                 mSlots[*front].mBufferState = BufferSlot::FREE;
    512                 // and we record the new buffer index in the queued list
    513                 *front = buf;
    514             }
    515         }
    516 
    517         mSlots[buf].mBufferState = BufferSlot::QUEUED;
    518         mSlots[buf].mCrop = mNextCrop;
    519         mSlots[buf].mTransform = mNextTransform;
    520         mSlots[buf].mScalingMode = mNextScalingMode;
    521         mSlots[buf].mTimestamp = timestamp;
    522         mDequeueCondition.signal();
    523 
    524         *outWidth = mDefaultWidth;
    525         *outHeight = mDefaultHeight;
    526         *outTransform = 0;
    527     } // scope for the lock
    528 
    529     // call back without lock held
    530     if (listener != 0) {
    531         listener->onFrameAvailable();
    532     }
    533     return OK;
    534 }
    535 
    536 void SurfaceTexture::cancelBuffer(int buf) {
    537     ST_LOGV("SurfaceTexture::cancelBuffer");
    538     Mutex::Autolock lock(mMutex);
    539 
    540     if (mAbandoned) {
    541         ST_LOGW("cancelBuffer: SurfaceTexture has been abandoned!");
    542         return;
    543     }
    544 
    545     if (buf < 0 || buf >= mBufferCount) {
    546         ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
    547                 mBufferCount, buf);
    548         return;
    549     } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
    550         ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
    551                 buf, mSlots[buf].mBufferState);
    552         return;
    553     }
    554     mSlots[buf].mBufferState = BufferSlot::FREE;
    555     mDequeueCondition.signal();
    556 }
    557 
    558 status_t SurfaceTexture::setCrop(const Rect& crop) {
    559     ST_LOGV("SurfaceTexture::setCrop");
    560     Mutex::Autolock lock(mMutex);
    561     if (mAbandoned) {
    562         ST_LOGE("setCrop: SurfaceTexture has been abandoned!");
    563         return NO_INIT;
    564     }
    565     mNextCrop = crop;
    566     return OK;
    567 }
    568 
    569 status_t SurfaceTexture::setTransform(uint32_t transform) {
    570     ST_LOGV("SurfaceTexture::setTransform");
    571     Mutex::Autolock lock(mMutex);
    572     if (mAbandoned) {
    573         ST_LOGE("setTransform: SurfaceTexture has been abandoned!");
    574         return NO_INIT;
    575     }
    576     mNextTransform = transform;
    577     return OK;
    578 }
    579 
    580 status_t SurfaceTexture::connect(int api,
    581         uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
    582     ST_LOGV("SurfaceTexture::connect(this=%p, %d)", this, api);
    583     Mutex::Autolock lock(mMutex);
    584 
    585     if (mAbandoned) {
    586         ST_LOGE("connect: SurfaceTexture has been abandoned!");
    587         return NO_INIT;
    588     }
    589 
    590     int err = NO_ERROR;
    591     switch (api) {
    592         case NATIVE_WINDOW_API_EGL:
    593         case NATIVE_WINDOW_API_CPU:
    594         case NATIVE_WINDOW_API_MEDIA:
    595         case NATIVE_WINDOW_API_CAMERA:
    596             if (mConnectedApi != NO_CONNECTED_API) {
    597                 ST_LOGE("connect: already connected (cur=%d, req=%d)",
    598                         mConnectedApi, api);
    599                 err = -EINVAL;
    600             } else {
    601                 mConnectedApi = api;
    602                 *outWidth = mDefaultWidth;
    603                 *outHeight = mDefaultHeight;
    604                 *outTransform = 0;
    605             }
    606             break;
    607         default:
    608             err = -EINVAL;
    609             break;
    610     }
    611     return err;
    612 }
    613 
    614 status_t SurfaceTexture::disconnect(int api) {
    615     ST_LOGV("SurfaceTexture::disconnect(this=%p, %d)", this, api);
    616     Mutex::Autolock lock(mMutex);
    617 
    618     if (mAbandoned) {
    619         ST_LOGE("disconnect: SurfaceTexture has been abandoned!");
    620         return NO_INIT;
    621     }
    622 
    623     int err = NO_ERROR;
    624     switch (api) {
    625         case NATIVE_WINDOW_API_EGL:
    626         case NATIVE_WINDOW_API_CPU:
    627         case NATIVE_WINDOW_API_MEDIA:
    628         case NATIVE_WINDOW_API_CAMERA:
    629             if (mConnectedApi == api) {
    630                 drainQueueAndFreeBuffersLocked();
    631                 mConnectedApi = NO_CONNECTED_API;
    632                 mNextCrop.makeInvalid();
    633                 mNextScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
    634                 mNextTransform = 0;
    635                 mDequeueCondition.signal();
    636             } else {
    637                 ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)",
    638                         mConnectedApi, api);
    639                 err = -EINVAL;
    640             }
    641             break;
    642         default:
    643             err = -EINVAL;
    644             break;
    645     }
    646     return err;
    647 }
    648 
    649 status_t SurfaceTexture::setScalingMode(int mode) {
    650     ST_LOGV("SurfaceTexture::setScalingMode(%d)", mode);
    651 
    652     switch (mode) {
    653         case NATIVE_WINDOW_SCALING_MODE_FREEZE:
    654         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
    655             break;
    656         default:
    657             return BAD_VALUE;
    658     }
    659 
    660     Mutex::Autolock lock(mMutex);
    661     mNextScalingMode = mode;
    662     return OK;
    663 }
    664 
    665 status_t SurfaceTexture::updateTexImage() {
    666     ST_LOGV("SurfaceTexture::updateTexImage");
    667     Mutex::Autolock lock(mMutex);
    668 
    669     if (mAbandoned) {
    670         ST_LOGE("calling updateTexImage() on an abandoned SurfaceTexture");
    671         return NO_INIT;
    672     }
    673 
    674     // In asynchronous mode the list is guaranteed to be one buffer
    675     // deep, while in synchronous mode we use the oldest buffer.
    676     if (!mQueue.empty()) {
    677         Fifo::iterator front(mQueue.begin());
    678         int buf = *front;
    679 
    680         // Update the GL texture object.
    681         EGLImageKHR image = mSlots[buf].mEglImage;
    682         if (image == EGL_NO_IMAGE_KHR) {
    683             EGLDisplay dpy = eglGetCurrentDisplay();
    684             if (mSlots[buf].mGraphicBuffer == 0) {
    685                 ST_LOGE("buffer at slot %d is null", buf);
    686                 return BAD_VALUE;
    687             }
    688             image = createImage(dpy, mSlots[buf].mGraphicBuffer);
    689             mSlots[buf].mEglImage = image;
    690             mSlots[buf].mEglDisplay = dpy;
    691             if (image == EGL_NO_IMAGE_KHR) {
    692                 // NOTE: if dpy was invalid, createImage() is guaranteed to
    693                 // fail. so we'd end up here.
    694                 return -EINVAL;
    695             }
    696         }
    697 
    698         GLint error;
    699         while ((error = glGetError()) != GL_NO_ERROR) {
    700             ST_LOGW("updateTexImage: clearing GL error: %#04x", error);
    701         }
    702 
    703         glBindTexture(mTexTarget, mTexName);
    704         glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image);
    705 
    706         bool failed = false;
    707         while ((error = glGetError()) != GL_NO_ERROR) {
    708             ST_LOGE("error binding external texture image %p (slot %d): %#04x",
    709                     image, buf, error);
    710             failed = true;
    711         }
    712         if (failed) {
    713             return -EINVAL;
    714         }
    715 
    716         if (mCurrentTexture != INVALID_BUFFER_SLOT) {
    717             // The current buffer becomes FREE if it was still in the queued
    718             // state. If it has already been given to the client
    719             // (synchronous mode), then it stays in DEQUEUED state.
    720             if (mSlots[mCurrentTexture].mBufferState == BufferSlot::QUEUED)
    721                 mSlots[mCurrentTexture].mBufferState = BufferSlot::FREE;
    722         }
    723 
    724         // Update the SurfaceTexture state.
    725         mCurrentTexture = buf;
    726         mCurrentTextureBuf = mSlots[buf].mGraphicBuffer;
    727         mCurrentCrop = mSlots[buf].mCrop;
    728         mCurrentTransform = mSlots[buf].mTransform;
    729         mCurrentScalingMode = mSlots[buf].mScalingMode;
    730         mCurrentTimestamp = mSlots[buf].mTimestamp;
    731         computeCurrentTransformMatrix();
    732 
    733         // Now that we've passed the point at which failures can happen,
    734         // it's safe to remove the buffer from the front of the queue.
    735         mQueue.erase(front);
    736         mDequeueCondition.signal();
    737     } else {
    738         // We always bind the texture even if we don't update its contents.
    739         glBindTexture(mTexTarget, mTexName);
    740     }
    741 
    742     return OK;
    743 }
    744 
    745 bool SurfaceTexture::isExternalFormat(uint32_t format)
    746 {
    747     switch (format) {
    748     // supported YUV formats
    749     case HAL_PIXEL_FORMAT_YV12:
    750     // Legacy/deprecated YUV formats
    751     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    752     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    753     case HAL_PIXEL_FORMAT_YCbCr_422_I:
    754         return true;
    755     }
    756 
    757     // Any OEM format needs to be considered
    758     if (format>=0x100 && format<=0x1FF)
    759         return true;
    760 
    761     return false;
    762 }
    763 
    764 GLenum SurfaceTexture::getCurrentTextureTarget() const {
    765     return mTexTarget;
    766 }
    767 
    768 void SurfaceTexture::getTransformMatrix(float mtx[16]) {
    769     Mutex::Autolock lock(mMutex);
    770     memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix));
    771 }
    772 
    773 void SurfaceTexture::computeCurrentTransformMatrix() {
    774     ST_LOGV("SurfaceTexture::computeCurrentTransformMatrix");
    775 
    776     float xform[16];
    777     for (int i = 0; i < 16; i++) {
    778         xform[i] = mtxIdentity[i];
    779     }
    780     if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
    781         float result[16];
    782         mtxMul(result, xform, mtxFlipH);
    783         for (int i = 0; i < 16; i++) {
    784             xform[i] = result[i];
    785         }
    786     }
    787     if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) {
    788         float result[16];
    789         mtxMul(result, xform, mtxFlipV);
    790         for (int i = 0; i < 16; i++) {
    791             xform[i] = result[i];
    792         }
    793     }
    794     if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
    795         float result[16];
    796         mtxMul(result, xform, mtxRot90);
    797         for (int i = 0; i < 16; i++) {
    798             xform[i] = result[i];
    799         }
    800     }
    801 
    802     sp<GraphicBuffer>& buf(mSlots[mCurrentTexture].mGraphicBuffer);
    803     float tx, ty, sx, sy;
    804     if (!mCurrentCrop.isEmpty()) {
    805         // In order to prevent bilinear sampling at the of the crop rectangle we
    806         // may need to shrink it by 2 texels in each direction.  Normally this
    807         // would just need to take 1/2 a texel off each end, but because the
    808         // chroma channels will likely be subsampled we need to chop off a whole
    809         // texel.  This will cause artifacts if someone does nearest sampling
    810         // with 1:1 pixel:texel ratio, but it's impossible to simultaneously
    811         // accomodate the bilinear and nearest sampling uses.
    812         //
    813         // If nearest sampling turns out to be a desirable usage of these
    814         // textures then we could add the ability to switch a SurfaceTexture to
    815         // nearest-mode.  Preferably, however, the image producers (video
    816         // decoder, camera, etc.) would simply not use a crop rectangle (or at
    817         // least not tell the framework about it) so that the GPU can do the
    818         // correct edge behavior.
    819         int xshrink = 0, yshrink = 0;
    820         if (mCurrentCrop.left > 0) {
    821             tx = float(mCurrentCrop.left + 1) / float(buf->getWidth());
    822             xshrink++;
    823         } else {
    824             tx = 0.0f;
    825         }
    826         if (mCurrentCrop.right < int32_t(buf->getWidth())) {
    827             xshrink++;
    828         }
    829         if (mCurrentCrop.bottom < int32_t(buf->getHeight())) {
    830             ty = (float(buf->getHeight() - mCurrentCrop.bottom) + 1.0f) /
    831                     float(buf->getHeight());
    832             yshrink++;
    833         } else {
    834             ty = 0.0f;
    835         }
    836         if (mCurrentCrop.top > 0) {
    837             yshrink++;
    838         }
    839         sx = float(mCurrentCrop.width() - xshrink) / float(buf->getWidth());
    840         sy = float(mCurrentCrop.height() - yshrink) / float(buf->getHeight());
    841     } else {
    842         tx = 0.0f;
    843         ty = 0.0f;
    844         sx = 1.0f;
    845         sy = 1.0f;
    846     }
    847     float crop[16] = {
    848         sx, 0, 0, 0,
    849         0, sy, 0, 0,
    850         0, 0, 1, 0,
    851         tx, ty, 0, 1,
    852     };
    853 
    854     float mtxBeforeFlipV[16];
    855     mtxMul(mtxBeforeFlipV, crop, xform);
    856 
    857     // SurfaceFlinger expects the top of its window textures to be at a Y
    858     // coordinate of 0, so SurfaceTexture must behave the same way.  We don't
    859     // want to expose this to applications, however, so we must add an
    860     // additional vertical flip to the transform after all the other transforms.
    861     mtxMul(mCurrentTransformMatrix, mtxFlipV, mtxBeforeFlipV);
    862 }
    863 
    864 nsecs_t SurfaceTexture::getTimestamp() {
    865     ST_LOGV("SurfaceTexture::getTimestamp");
    866     Mutex::Autolock lock(mMutex);
    867     return mCurrentTimestamp;
    868 }
    869 
    870 void SurfaceTexture::setFrameAvailableListener(
    871         const sp<FrameAvailableListener>& listener) {
    872     ST_LOGV("SurfaceTexture::setFrameAvailableListener");
    873     Mutex::Autolock lock(mMutex);
    874     mFrameAvailableListener = listener;
    875 }
    876 
    877 void SurfaceTexture::freeBufferLocked(int i) {
    878     mSlots[i].mGraphicBuffer = 0;
    879     mSlots[i].mBufferState = BufferSlot::FREE;
    880     if (mSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
    881         eglDestroyImageKHR(mSlots[i].mEglDisplay, mSlots[i].mEglImage);
    882         mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
    883         mSlots[i].mEglDisplay = EGL_NO_DISPLAY;
    884     }
    885 }
    886 
    887 void SurfaceTexture::freeAllBuffersLocked() {
    888     LOGW_IF(!mQueue.isEmpty(),
    889             "freeAllBuffersLocked called but mQueue is not empty");
    890     mCurrentTexture = INVALID_BUFFER_SLOT;
    891     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
    892         freeBufferLocked(i);
    893     }
    894 }
    895 
    896 void SurfaceTexture::freeAllBuffersExceptHeadLocked() {
    897     LOGW_IF(!mQueue.isEmpty(),
    898             "freeAllBuffersExceptCurrentLocked called but mQueue is not empty");
    899     int head = -1;
    900     if (!mQueue.empty()) {
    901         Fifo::iterator front(mQueue.begin());
    902         head = *front;
    903     }
    904     mCurrentTexture = INVALID_BUFFER_SLOT;
    905     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
    906         if (i != head) {
    907             freeBufferLocked(i);
    908         }
    909     }
    910 }
    911 
    912 status_t SurfaceTexture::drainQueueLocked() {
    913     while (mSynchronousMode && !mQueue.isEmpty()) {
    914         mDequeueCondition.wait(mMutex);
    915         if (mAbandoned) {
    916             ST_LOGE("drainQueueLocked: SurfaceTexture has been abandoned!");
    917             return NO_INIT;
    918         }
    919         if (mConnectedApi == NO_CONNECTED_API) {
    920             ST_LOGE("drainQueueLocked: SurfaceTexture is not connected!");
    921             return NO_INIT;
    922         }
    923     }
    924     return NO_ERROR;
    925 }
    926 
    927 status_t SurfaceTexture::drainQueueAndFreeBuffersLocked() {
    928     status_t err = drainQueueLocked();
    929     if (err == NO_ERROR) {
    930         if (mSynchronousMode) {
    931             freeAllBuffersLocked();
    932         } else {
    933             freeAllBuffersExceptHeadLocked();
    934         }
    935     }
    936     return err;
    937 }
    938 
    939 EGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy,
    940         const sp<GraphicBuffer>& graphicBuffer) {
    941     EGLClientBuffer cbuf = (EGLClientBuffer)graphicBuffer->getNativeBuffer();
    942     EGLint attrs[] = {
    943         EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE,
    944         EGL_NONE,
    945     };
    946     EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT,
    947             EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs);
    948     if (image == EGL_NO_IMAGE_KHR) {
    949         EGLint error = eglGetError();
    950         ST_LOGE("error creating EGLImage: %#x", error);
    951     }
    952     return image;
    953 }
    954 
    955 sp<GraphicBuffer> SurfaceTexture::getCurrentBuffer() const {
    956     Mutex::Autolock lock(mMutex);
    957     return mCurrentTextureBuf;
    958 }
    959 
    960 Rect SurfaceTexture::getCurrentCrop() const {
    961     Mutex::Autolock lock(mMutex);
    962     return mCurrentCrop;
    963 }
    964 
    965 uint32_t SurfaceTexture::getCurrentTransform() const {
    966     Mutex::Autolock lock(mMutex);
    967     return mCurrentTransform;
    968 }
    969 
    970 uint32_t SurfaceTexture::getCurrentScalingMode() const {
    971     Mutex::Autolock lock(mMutex);
    972     return mCurrentScalingMode;
    973 }
    974 
    975 int SurfaceTexture::query(int what, int* outValue)
    976 {
    977     Mutex::Autolock lock(mMutex);
    978 
    979     if (mAbandoned) {
    980         ST_LOGE("query: SurfaceTexture has been abandoned!");
    981         return NO_INIT;
    982     }
    983 
    984     int value;
    985     switch (what) {
    986     case NATIVE_WINDOW_WIDTH:
    987         value = mDefaultWidth;
    988         break;
    989     case NATIVE_WINDOW_HEIGHT:
    990         value = mDefaultHeight;
    991         break;
    992     case NATIVE_WINDOW_FORMAT:
    993         value = mPixelFormat;
    994         break;
    995     case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
    996         value = mSynchronousMode ?
    997                 (MIN_UNDEQUEUED_BUFFERS-1) : MIN_UNDEQUEUED_BUFFERS;
    998         break;
    999     default:
   1000         return BAD_VALUE;
   1001     }
   1002     outValue[0] = value;
   1003     return NO_ERROR;
   1004 }
   1005 
   1006 void SurfaceTexture::abandon() {
   1007     Mutex::Autolock lock(mMutex);
   1008     mQueue.clear();
   1009     mAbandoned = true;
   1010     mCurrentTextureBuf.clear();
   1011     freeAllBuffersLocked();
   1012     mDequeueCondition.signal();
   1013 }
   1014 
   1015 void SurfaceTexture::setName(const String8& name) {
   1016     mName = name;
   1017 }
   1018 
   1019 void SurfaceTexture::dump(String8& result) const
   1020 {
   1021     char buffer[1024];
   1022     dump(result, "", buffer, 1024);
   1023 }
   1024 
   1025 void SurfaceTexture::dump(String8& result, const char* prefix,
   1026         char* buffer, size_t SIZE) const
   1027 {
   1028     Mutex::Autolock _l(mMutex);
   1029     snprintf(buffer, SIZE,
   1030             "%smBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
   1031             "mPixelFormat=%d, mTexName=%d\n",
   1032             prefix, mBufferCount, mSynchronousMode, mDefaultWidth,
   1033             mDefaultHeight, mPixelFormat, mTexName);
   1034     result.append(buffer);
   1035 
   1036     String8 fifo;
   1037     int fifoSize = 0;
   1038     Fifo::const_iterator i(mQueue.begin());
   1039     while (i != mQueue.end()) {
   1040         snprintf(buffer, SIZE, "%02d ", *i++);
   1041         fifoSize++;
   1042         fifo.append(buffer);
   1043     }
   1044 
   1045     snprintf(buffer, SIZE,
   1046             "%scurrent: {crop=[%d,%d,%d,%d], transform=0x%02x, current=%d}\n"
   1047             "%snext   : {crop=[%d,%d,%d,%d], transform=0x%02x, FIFO(%d)={%s}}\n"
   1048             ,
   1049             prefix, mCurrentCrop.left,
   1050             mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom,
   1051             mCurrentTransform, mCurrentTexture,
   1052             prefix, mNextCrop.left, mNextCrop.top, mNextCrop.right,
   1053             mNextCrop.bottom, mNextTransform, fifoSize, fifo.string()
   1054     );
   1055     result.append(buffer);
   1056 
   1057     struct {
   1058         const char * operator()(int state) const {
   1059             switch (state) {
   1060                 case BufferSlot::DEQUEUED: return "DEQUEUED";
   1061                 case BufferSlot::QUEUED: return "QUEUED";
   1062                 case BufferSlot::FREE: return "FREE";
   1063                 default: return "Unknown";
   1064             }
   1065         }
   1066     } stateName;
   1067 
   1068     for (int i=0 ; i<mBufferCount ; i++) {
   1069         const BufferSlot& slot(mSlots[i]);
   1070         snprintf(buffer, SIZE,
   1071                 "%s%s[%02d] "
   1072                 "state=%-8s, crop=[%d,%d,%d,%d], "
   1073                 "transform=0x%02x, timestamp=%lld",
   1074                 prefix, (i==mCurrentTexture)?">":" ", i,
   1075                 stateName(slot.mBufferState),
   1076                 slot.mCrop.left, slot.mCrop.top, slot.mCrop.right,
   1077                 slot.mCrop.bottom, slot.mTransform, slot.mTimestamp
   1078         );
   1079         result.append(buffer);
   1080 
   1081         const sp<GraphicBuffer>& buf(slot.mGraphicBuffer);
   1082         if (buf != NULL) {
   1083             snprintf(buffer, SIZE,
   1084                     ", %p [%4ux%4u:%4u,%3X]",
   1085                     buf->handle, buf->width, buf->height, buf->stride,
   1086                     buf->format);
   1087             result.append(buffer);
   1088         }
   1089         result.append("\n");
   1090     }
   1091 }
   1092 
   1093 static void mtxMul(float out[16], const float a[16], const float b[16]) {
   1094     out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3];
   1095     out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3];
   1096     out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3];
   1097     out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3];
   1098 
   1099     out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7];
   1100     out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7];
   1101     out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7];
   1102     out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7];
   1103 
   1104     out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11];
   1105     out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11];
   1106     out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11];
   1107     out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11];
   1108 
   1109     out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15];
   1110     out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15];
   1111     out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15];
   1112     out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15];
   1113 }
   1114 
   1115 }; // namespace android
   1116