SurfaceTexture.cpp revision b598fb90727be45e926a11abefc319819a733540
168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis/*
268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * Copyright (C) 2010 The Android Open Source Project
368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis *
468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * Licensed under the Apache License, Version 2.0 (the "License");
568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * you may not use this file except in compliance with the License.
668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * You may obtain a copy of the License at
768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis *
868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis *      http://www.apache.org/licenses/LICENSE-2.0
968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis *
1068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * Unless required by applicable law or agreed to in writing, software
1168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * distributed under the License is distributed on an "AS IS" BASIS,
1268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * See the License for the specific language governing permissions and
1468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis * limitations under the License.
1568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis */
1668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
1768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#define LOG_TAG "SurfaceTexture"
187dc00d5eb27de41f93a7e232b3cd374c84eb77d1Jamie Gennis//#define LOG_NDEBUG 0
1968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
2068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#define GL_GLEXT_PROTOTYPES
2168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#define EGL_EGLEXT_PROTOTYPES
2268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
2368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#include <EGL/egl.h>
2468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#include <EGL/eglext.h>
2568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#include <GLES2/gl2.h>
2668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#include <GLES2/gl2ext.h>
2768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
2868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#include <gui/SurfaceTexture.h>
2968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
3068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#include <surfaceflinger/ISurfaceComposer.h>
3168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#include <surfaceflinger/SurfaceComposerClient.h>
3268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
3368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis#include <utils/Log.h>
3468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
3568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennisnamespace android {
3668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
37b598fb90727be45e926a11abefc319819a733540Jamie Gennis// Transform matrices
38b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatic float mtxIdentity[16] = {
39b598fb90727be45e926a11abefc319819a733540Jamie Gennis    1, 0, 0, 0,
40b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 1, 0, 0,
41b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 0, 1, 0,
42b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 0, 0, 1,
43b598fb90727be45e926a11abefc319819a733540Jamie Gennis};
44b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatic float mtxFlipH[16] = {
45b598fb90727be45e926a11abefc319819a733540Jamie Gennis    -1, 0, 0, 0,
46b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 1, 0, 0,
47b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 0, 1, 0,
48b598fb90727be45e926a11abefc319819a733540Jamie Gennis    1, 0, 0, 1,
49b598fb90727be45e926a11abefc319819a733540Jamie Gennis};
50b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatic float mtxFlipV[16] = {
51b598fb90727be45e926a11abefc319819a733540Jamie Gennis    1, 0, 0, 0,
52b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, -1, 0, 0,
53b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 0, 1, 0,
54b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 1, 0, 1,
55b598fb90727be45e926a11abefc319819a733540Jamie Gennis};
56b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatic float mtxRot90[16] = {
57b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 1, 0, 0,
58b598fb90727be45e926a11abefc319819a733540Jamie Gennis    -1, 0, 0, 0,
59b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 0, 1, 0,
60b598fb90727be45e926a11abefc319819a733540Jamie Gennis    1, 0, 0, 1,
61b598fb90727be45e926a11abefc319819a733540Jamie Gennis};
62b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatic float mtxRot180[16] = {
63b598fb90727be45e926a11abefc319819a733540Jamie Gennis    -1, 0, 0, 0,
64b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, -1, 0, 0,
65b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 0, 1, 0,
66b598fb90727be45e926a11abefc319819a733540Jamie Gennis    1, 1, 0, 1,
67b598fb90727be45e926a11abefc319819a733540Jamie Gennis};
68b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatic float mtxRot270[16] = {
69b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, -1, 0, 0,
70b598fb90727be45e926a11abefc319819a733540Jamie Gennis    1, 0, 0, 0,
71b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 0, 1, 0,
72b598fb90727be45e926a11abefc319819a733540Jamie Gennis    0, 1, 0, 1,
73b598fb90727be45e926a11abefc319819a733540Jamie Gennis};
74b598fb90727be45e926a11abefc319819a733540Jamie Gennis
75b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]);
76b598fb90727be45e926a11abefc319819a733540Jamie Gennis
7768e4a7ac849b681b1fb769857fc04f64262480c4Jamie GennisSurfaceTexture::SurfaceTexture(GLuint tex) :
7868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    mBufferCount(MIN_BUFFER_SLOTS), mCurrentTexture(INVALID_BUFFER_SLOT),
7968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    mLastQueued(INVALID_BUFFER_SLOT), mTexName(tex) {
807dc00d5eb27de41f93a7e232b3cd374c84eb77d1Jamie Gennis    LOGV("SurfaceTexture::SurfaceTexture");
81fd804f31a36c31661859b53bbee1bb408462ddcaJamie Gennis    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
82fd804f31a36c31661859b53bbee1bb408462ddcaJamie Gennis        mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
83fd804f31a36c31661859b53bbee1bb408462ddcaJamie Gennis        mSlots[i].mEglDisplay = EGL_NO_DISPLAY;
84fd804f31a36c31661859b53bbee1bb408462ddcaJamie Gennis        mSlots[i].mOwnedByClient = false;
85fd804f31a36c31661859b53bbee1bb408462ddcaJamie Gennis    }
8668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
8768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
8868e4a7ac849b681b1fb769857fc04f64262480c4Jamie GennisSurfaceTexture::~SurfaceTexture() {
897dc00d5eb27de41f93a7e232b3cd374c84eb77d1Jamie Gennis    LOGV("SurfaceTexture::~SurfaceTexture");
9068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    freeAllBuffers();
9168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
9268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
9368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennisstatus_t SurfaceTexture::setBufferCount(int bufferCount) {
947dc00d5eb27de41f93a7e232b3cd374c84eb77d1Jamie Gennis    LOGV("SurfaceTexture::setBufferCount");
9568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    Mutex::Autolock lock(mMutex);
9668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    freeAllBuffers();
9768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    mBufferCount = bufferCount;
98d369dc42506ec003f1839bb9e27edada411324b5Jamie Gennis    mCurrentTexture = INVALID_BUFFER_SLOT;
99d369dc42506ec003f1839bb9e27edada411324b5Jamie Gennis    mLastQueued = INVALID_BUFFER_SLOT;
10068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    return OK;
10168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
10268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
10368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennissp<GraphicBuffer> SurfaceTexture::requestBuffer(int buf,
10468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
1057dc00d5eb27de41f93a7e232b3cd374c84eb77d1Jamie Gennis    LOGV("SurfaceTexture::requestBuffer");
10668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    Mutex::Autolock lock(mMutex);
10768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    if (buf < 0 || mBufferCount <= buf) {
10868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        LOGE("requestBuffer: slot index out of range [0, %d]: %d",
10968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis                mBufferCount, buf);
11068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        return 0;
11168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    }
11268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    usage |= GraphicBuffer::USAGE_HW_TEXTURE;
11368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    sp<ISurfaceComposer> composer(ComposerService::getComposerService());
11468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    sp<GraphicBuffer> graphicBuffer(composer->createGraphicBuffer(w, h,
11568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            format, usage));
11668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    if (graphicBuffer == 0) {
11768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        LOGE("requestBuffer: SurfaceComposer::createGraphicBuffer failed");
11868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    } else {
11968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        mSlots[buf].mGraphicBuffer = graphicBuffer;
12068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        if (mSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) {
12168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            eglDestroyImageKHR(mSlots[buf].mEglDisplay, mSlots[buf].mEglImage);
12268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            mSlots[buf].mEglImage = EGL_NO_IMAGE_KHR;
12368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
12468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        }
12568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    }
12668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    return graphicBuffer;
12768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
12868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
12968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennisstatus_t SurfaceTexture::dequeueBuffer(int *buf) {
1307dc00d5eb27de41f93a7e232b3cd374c84eb77d1Jamie Gennis    LOGV("SurfaceTexture::dequeueBuffer");
13168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    Mutex::Autolock lock(mMutex);
13268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    int found = INVALID_BUFFER_SLOT;
13368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    for (int i = 0; i < mBufferCount; i++) {
13468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        if (!mSlots[i].mOwnedByClient && i != mCurrentTexture) {
13568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            mSlots[i].mOwnedByClient = true;
13668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            found = i;
13768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            break;
13868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        }
13968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    }
14068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    if (found == INVALID_BUFFER_SLOT) {
14168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        return -EBUSY;
14268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    }
14368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    *buf = found;
14468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    return OK;
14568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
14668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
14768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennisstatus_t SurfaceTexture::queueBuffer(int buf) {
1487dc00d5eb27de41f93a7e232b3cd374c84eb77d1Jamie Gennis    LOGV("SurfaceTexture::queueBuffer");
14968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    Mutex::Autolock lock(mMutex);
15068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    if (buf < 0 || mBufferCount <= buf) {
15168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        LOGE("queueBuffer: slot index out of range [0, %d]: %d",
15268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis                mBufferCount, buf);
15368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        return -EINVAL;
15468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    } else if (!mSlots[buf].mOwnedByClient) {
15568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        LOGE("queueBuffer: slot %d is not owned by the client", buf);
15668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        return -EINVAL;
15768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    } else if (mSlots[buf].mGraphicBuffer == 0) {
15868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        LOGE("queueBuffer: slot %d was enqueued without requesting a buffer",
15968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis                buf);
16068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        return -EINVAL;
16168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    }
16268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    mSlots[buf].mOwnedByClient = false;
16368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    mLastQueued = buf;
164b598fb90727be45e926a11abefc319819a733540Jamie Gennis    mLastQueuedCrop = mNextCrop;
165b598fb90727be45e926a11abefc319819a733540Jamie Gennis    mLastQueuedTransform = mNextTransform;
16668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    return OK;
16768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
16868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
16968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennisvoid SurfaceTexture::cancelBuffer(int buf) {
1707dc00d5eb27de41f93a7e232b3cd374c84eb77d1Jamie Gennis    LOGV("SurfaceTexture::cancelBuffer");
17168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    Mutex::Autolock lock(mMutex);
17268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    if (buf < 0 || mBufferCount <= buf) {
17368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        LOGE("cancelBuffer: slot index out of range [0, %d]: %d", mBufferCount,
17468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis                buf);
17568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        return;
17668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    } else if (!mSlots[buf].mOwnedByClient) {
17768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        LOGE("cancelBuffer: slot %d is not owned by the client", buf);
17868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        return;
17968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    }
18068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    mSlots[buf].mOwnedByClient = false;
18168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
18268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
183b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatus_t SurfaceTexture::setCrop(const Rect& crop) {
1847dc00d5eb27de41f93a7e232b3cd374c84eb77d1Jamie Gennis    LOGV("SurfaceTexture::setCrop");
18568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    Mutex::Autolock lock(mMutex);
186b598fb90727be45e926a11abefc319819a733540Jamie Gennis    mNextCrop = crop;
18768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    return OK;
18868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
18968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
19068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennisstatus_t SurfaceTexture::setTransform(uint32_t transform) {
1917dc00d5eb27de41f93a7e232b3cd374c84eb77d1Jamie Gennis    LOGV("SurfaceTexture::setTransform");
19268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    Mutex::Autolock lock(mMutex);
193b598fb90727be45e926a11abefc319819a733540Jamie Gennis    mNextTransform = transform;
19468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    return OK;
19568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
19668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
19768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennisstatus_t SurfaceTexture::updateTexImage() {
1987dc00d5eb27de41f93a7e232b3cd374c84eb77d1Jamie Gennis    LOGV("SurfaceTexture::updateTexImage");
19968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    Mutex::Autolock lock(mMutex);
20068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
20168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    // We always bind the texture even if we don't update its contents.
20268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTexName);
20368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
20468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    // Initially both mCurrentTexture and mLastQueued are INVALID_BUFFER_SLOT,
20568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    // so this check will fail until a buffer gets queued.
20668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    if (mCurrentTexture != mLastQueued) {
207b598fb90727be45e926a11abefc319819a733540Jamie Gennis        // Update the SurfaceTexture state.
20868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        mCurrentTexture = mLastQueued;
209b598fb90727be45e926a11abefc319819a733540Jamie Gennis        mCurrentCrop = mLastQueuedCrop;
210b598fb90727be45e926a11abefc319819a733540Jamie Gennis        mCurrentTransform = mLastQueuedTransform;
211b598fb90727be45e926a11abefc319819a733540Jamie Gennis
212b598fb90727be45e926a11abefc319819a733540Jamie Gennis        // Update the GL texture object.
21368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        EGLImageKHR image = mSlots[mCurrentTexture].mEglImage;
21468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        if (image == EGL_NO_IMAGE_KHR) {
21568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            EGLDisplay dpy = eglGetCurrentDisplay();
21668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            sp<GraphicBuffer> graphicBuffer = mSlots[mCurrentTexture].mGraphicBuffer;
21768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            image = createImage(dpy, graphicBuffer);
21868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            mSlots[mCurrentTexture].mEglImage = image;
21968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            mSlots[mCurrentTexture].mEglDisplay = dpy;
22068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        }
22168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)image);
22268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        GLint error = glGetError();
22368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        if (error != GL_NO_ERROR) {
22468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            LOGE("error binding external texture image %p (slot %d): %#04x",
22568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis                    image, mCurrentTexture, error);
22668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            return -EINVAL;
22768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        }
22868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    }
22968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    return OK;
23068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
23168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
232b598fb90727be45e926a11abefc319819a733540Jamie Gennisvoid SurfaceTexture::getTransformMatrix(float mtx[16]) {
233b598fb90727be45e926a11abefc319819a733540Jamie Gennis    LOGV("SurfaceTexture::updateTexImage");
234b598fb90727be45e926a11abefc319819a733540Jamie Gennis    Mutex::Autolock lock(mMutex);
235b598fb90727be45e926a11abefc319819a733540Jamie Gennis
236b598fb90727be45e926a11abefc319819a733540Jamie Gennis    float* xform = mtxIdentity;
237b598fb90727be45e926a11abefc319819a733540Jamie Gennis    switch (mCurrentTransform) {
238b598fb90727be45e926a11abefc319819a733540Jamie Gennis        case 0:
239b598fb90727be45e926a11abefc319819a733540Jamie Gennis            xform = mtxIdentity;
240b598fb90727be45e926a11abefc319819a733540Jamie Gennis            break;
241b598fb90727be45e926a11abefc319819a733540Jamie Gennis        case NATIVE_WINDOW_TRANSFORM_FLIP_H:
242b598fb90727be45e926a11abefc319819a733540Jamie Gennis            xform = mtxFlipH;
243b598fb90727be45e926a11abefc319819a733540Jamie Gennis            break;
244b598fb90727be45e926a11abefc319819a733540Jamie Gennis        case NATIVE_WINDOW_TRANSFORM_FLIP_V:
245b598fb90727be45e926a11abefc319819a733540Jamie Gennis            xform = mtxFlipV;
246b598fb90727be45e926a11abefc319819a733540Jamie Gennis            break;
247b598fb90727be45e926a11abefc319819a733540Jamie Gennis        case NATIVE_WINDOW_TRANSFORM_ROT_90:
248b598fb90727be45e926a11abefc319819a733540Jamie Gennis            xform = mtxRot90;
249b598fb90727be45e926a11abefc319819a733540Jamie Gennis            break;
250b598fb90727be45e926a11abefc319819a733540Jamie Gennis        case NATIVE_WINDOW_TRANSFORM_ROT_180:
251b598fb90727be45e926a11abefc319819a733540Jamie Gennis            xform = mtxRot180;
252b598fb90727be45e926a11abefc319819a733540Jamie Gennis            break;
253b598fb90727be45e926a11abefc319819a733540Jamie Gennis        case NATIVE_WINDOW_TRANSFORM_ROT_270:
254b598fb90727be45e926a11abefc319819a733540Jamie Gennis            xform = mtxRot270;
255b598fb90727be45e926a11abefc319819a733540Jamie Gennis            break;
256b598fb90727be45e926a11abefc319819a733540Jamie Gennis        default:
257b598fb90727be45e926a11abefc319819a733540Jamie Gennis            LOGE("getTransformMatrix: unknown transform: %d", mCurrentTransform);
258b598fb90727be45e926a11abefc319819a733540Jamie Gennis    }
259b598fb90727be45e926a11abefc319819a733540Jamie Gennis
260b598fb90727be45e926a11abefc319819a733540Jamie Gennis    sp<GraphicBuffer>& buf(mSlots[mCurrentTexture].mGraphicBuffer);
261b598fb90727be45e926a11abefc319819a733540Jamie Gennis    float tx = float(mCurrentCrop.left) / float(buf->getWidth());
262b598fb90727be45e926a11abefc319819a733540Jamie Gennis    float ty = float(mCurrentCrop.bottom) / float(buf->getHeight());
263b598fb90727be45e926a11abefc319819a733540Jamie Gennis    float sx = float(mCurrentCrop.width()) / float(buf->getWidth());
264b598fb90727be45e926a11abefc319819a733540Jamie Gennis    float sy = float(mCurrentCrop.height()) / float(buf->getHeight());
265b598fb90727be45e926a11abefc319819a733540Jamie Gennis    float crop[16] = {
266b598fb90727be45e926a11abefc319819a733540Jamie Gennis        sx, 0, 0, sx*tx,
267b598fb90727be45e926a11abefc319819a733540Jamie Gennis        0, sy, 0, sy*ty,
268b598fb90727be45e926a11abefc319819a733540Jamie Gennis        0, 0, 1, 0,
269b598fb90727be45e926a11abefc319819a733540Jamie Gennis        0, 0, 0, 1,
270b598fb90727be45e926a11abefc319819a733540Jamie Gennis    };
271b598fb90727be45e926a11abefc319819a733540Jamie Gennis
272b598fb90727be45e926a11abefc319819a733540Jamie Gennis    mtxMul(mtx, crop, xform);
273b598fb90727be45e926a11abefc319819a733540Jamie Gennis}
274b598fb90727be45e926a11abefc319819a733540Jamie Gennis
27568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennisvoid SurfaceTexture::freeAllBuffers() {
27668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
27768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        mSlots[i].mGraphicBuffer = 0;
27868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        mSlots[i].mOwnedByClient = false;
27968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        if (mSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
28068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            eglDestroyImageKHR(mSlots[i].mEglDisplay, mSlots[i].mEglImage);
28168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
28268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            mSlots[i].mEglDisplay = EGL_NO_DISPLAY;
28368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        }
28468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    }
28568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
28668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
28768e4a7ac849b681b1fb769857fc04f64262480c4Jamie GennisEGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy,
28868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        const sp<GraphicBuffer>& graphicBuffer) {
28968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    EGLClientBuffer cbuf = (EGLClientBuffer)graphicBuffer->getNativeBuffer();
29068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    EGLint attrs[] = {
29168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE,
29268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        EGL_NONE,
29368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    };
29468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT,
29568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis            EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs);
29668e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    EGLint error = eglGetError();
29768e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    if (error != EGL_SUCCESS) {
29868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        LOGE("error creating EGLImage: %#x", error);
29968e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    } else if (image == EGL_NO_IMAGE_KHR) {
30068e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis        LOGE("no error reported, but no image was returned by "
30168e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis                "eglCreateImageKHR");
30268e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    }
30368e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis    return image;
30468e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}
30568e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis
306b598fb90727be45e926a11abefc319819a733540Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]) {
307b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3];
308b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3];
309b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3];
310b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3];
311b598fb90727be45e926a11abefc319819a733540Jamie Gennis
312b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7];
313b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7];
314b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7];
315b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7];
316b598fb90727be45e926a11abefc319819a733540Jamie Gennis
317b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11];
318b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11];
319b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11];
320b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11];
321b598fb90727be45e926a11abefc319819a733540Jamie Gennis
322b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15];
323b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15];
324b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15];
325b598fb90727be45e926a11abefc319819a733540Jamie Gennis    out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15];
326b598fb90727be45e926a11abefc319819a733540Jamie Gennis}
327b598fb90727be45e926a11abefc319819a733540Jamie Gennis
32868e4a7ac849b681b1fb769857fc04f64262480c4Jamie Gennis}; // namespace android
329