GLConsumer.cpp revision 9fea3421ffddf6480f57f55a25936a886043d909
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" 181c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS 19e70d8b43938e17beebcc0c97a9373a1906f6f2bfJamie Gennis//#define LOG_NDEBUG 0 208ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 218ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#define GL_GLEXT_PROTOTYPES 228ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#define EGL_EGLEXT_PROTOTYPES 238ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 248ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <EGL/egl.h> 258ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <EGL/eglext.h> 268ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <GLES2/gl2.h> 278ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <GLES2/gl2ext.h> 288ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 299fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis#include <hardware/hardware.h> 309fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 3190ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/IGraphicBufferAlloc.h> 3290ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/ISurfaceComposer.h> 3390ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/SurfaceComposerClient.h> 3490ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/SurfaceTexture.h> 3541f673c9b3aac0d96e41c928845c39186d565212Mathias Agopian 3690ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <private/gui/ComposerService.h> 378ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 388ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <utils/Log.h> 3968c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian#include <utils/String8.h> 401c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 418ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 4286edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis// This compile option makes SurfaceTexture use the EGL_KHR_fence_sync extension 4386edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis// to synchronize access to the buffers. It will cause dequeueBuffer to stall, 4486edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis// waiting for the GL reads for the buffer being dequeued to complete before 4586edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis// allowing the buffer to be dequeued. 4686edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis#ifdef USE_FENCE_SYNC 4786edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis#ifdef ALLOW_DEQUEUE_CURRENT_BUFFER 4886edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis#error "USE_FENCE_SYNC and ALLOW_DEQUEUE_CURRENT_BUFFER are incompatible" 4986edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis#endif 5086edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis#endif 5186edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis 52fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis// Macros for including the SurfaceTexture name in log messages 536807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block#define ST_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__) 549d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block#define ST_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__) 55a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block#define ST_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__) 5632397c1cd3327905173b36baa6fd1c579bc328ffSteve Block#define ST_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__) 57e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block#define ST_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__) 5829b5762efc359022168e5099c1d17925444d3147Mathias Agopian 598ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennisnamespace android { 608ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 61f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis// Transform matrices 62f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxIdentity[16] = { 63f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 0, 64f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 65f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 66f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 0, 1, 67f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 68f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxFlipH[16] = { 69f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis -1, 0, 0, 0, 70f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 71f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 72f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 1, 73f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 74f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxFlipV[16] = { 75f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 0, 76f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, -1, 0, 0, 77f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 78f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 1, 79f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 80f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxRot90[16] = { 81f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 82f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis -1, 0, 0, 0, 83f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 84f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 1, 85f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 86f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxRot180[16] = { 87f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis -1, 0, 0, 0, 88f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, -1, 0, 0, 89f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 90f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 1, 0, 1, 91f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 92f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxRot270[16] = { 93f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, -1, 0, 0, 94f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 0, 95f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 96f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 1, 97f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 98f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 99f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]); 100f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 101fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis 102fb1b5a2f333800574b0da435d1200cf9b13d723fJamie GennisSurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode, 103b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue) : 1049fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase(bufferQueue == 0 ? new BufferQueue(allowSynchronousMode) : bufferQueue), 1051d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTransform(0), 1061d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTimestamp(0), 1075c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis mFilteringEnabled(true), 108b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mTexName(tex), 10986edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis#ifdef USE_FENCE_SYNC 11086edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis mUseFenceSync(useFenceSync), 11186edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis#else 11286edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis mUseFenceSync(false), 11386edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis#endif 114eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mTexTarget(texTarget), 115ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglDisplay(EGL_NO_DISPLAY), 116ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglContext(EGL_NO_CONTEXT), 11774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), 11874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached(true) 1196b091c53000c843211c218ce40287a7edca9bc63Daniel Lam{ 1206ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("SurfaceTexture"); 121b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 122fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis memcpy(mCurrentTransformMatrix, mtxIdentity, 123fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis sizeof(mCurrentTransformMatrix)); 124fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1259fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mBufferQueue->setConsumerUsageBits(DEFAULT_USAGE_FLAGS); 1268ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 1278ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 1288072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopianstatus_t SurfaceTexture::setBufferCountServer(int bufferCount) { 1298072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian Mutex::Autolock lock(mMutex); 130b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setBufferCountServer(bufferCount); 1318072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian} 1328072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 1338ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 134a5c75c01620179ce00812354778a29a80d76e71fMathias Agopianstatus_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h) 135a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian{ 136b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 137016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam mDefaultWidth = w; 138016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam mDefaultHeight = h; 139b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setDefaultBufferSize(w, h); 140a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian} 141a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian 1428ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennisstatus_t SurfaceTexture::updateTexImage() { 1432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return SurfaceTexture::updateTexImage(NULL); 1442c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian} 1452c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 1469fea3421ffddf6480f57f55a25936a886043d909Jamie Gennisstatus_t SurfaceTexture::acquireBufferLocked(BufferQueue::BufferItem *item) { 1479fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis status_t err = ConsumerBase::acquireBufferLocked(item); 1489fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (err != NO_ERROR) { 1499fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return err; 1509fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 1519fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 1529fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis int slot = item->mBuf; 1539fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (item->mGraphicBuffer != NULL) { 1549fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (mEglSlots[slot].mEglImage != EGL_NO_IMAGE_KHR) { 1559fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis eglDestroyImageKHR(mEglDisplay, mEglSlots[slot].mEglImage); 1569fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[slot].mEglImage = EGL_NO_IMAGE_KHR; 1579fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 1589fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 1599fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 1609fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis // Update the GL texture object. We may have to do this even when 1619fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis // item.mGraphicBuffer == NULL, if we destroyed the EGLImage when 1629fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis // detaching from a context but the buffer has not been re-allocated. 1639fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (mEglSlots[slot].mEglImage == EGL_NO_IMAGE_KHR) { 1649fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis EGLImageKHR image = createImage(mEglDisplay, mSlots[slot].mGraphicBuffer); 1659fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (image == EGL_NO_IMAGE_KHR) { 1669fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return UNKNOWN_ERROR; 1679fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 1689fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[slot].mEglImage = image; 1699fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 1709fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 1719fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return NO_ERROR; 1729fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis} 1739fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 1749fea3421ffddf6480f57f55a25936a886043d909Jamie Gennisstatus_t SurfaceTexture::releaseBufferLocked(int buf, EGLDisplay display, 1759fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis EGLSyncKHR eglFence, const sp<Fence>& fence) { 1769fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis status_t err = ConsumerBase::releaseBufferLocked(buf, mEglDisplay, 1779fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis eglFence, fence); 1789fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 1799fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[mCurrentTexture].mEglFence = EGL_NO_SYNC_KHR; 1809fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 1819fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return err; 1829fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis} 1839fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 1842c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopianstatus_t SurfaceTexture::updateTexImage(BufferRejecter* rejecter) { 1851c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 1866ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("updateTexImage"); 1878ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis Mutex::Autolock lock(mMutex); 1888ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 1899abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam status_t err = NO_ERROR; 1909abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 191e47498f8f258967ff62d070f08ff2dadd4ae2b56Mathias Agopian if (mAbandoned) { 19274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("updateTexImage: SurfaceTexture is abandoned!"); 1938e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian return NO_INIT; 194e47498f8f258967ff62d070f08ff2dadd4ae2b56Mathias Agopian } 195e47498f8f258967ff62d070f08ff2dadd4ae2b56Mathias Agopian 19674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (!mAttached) { 19774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("updateTexImage: SurfaceTexture is not attached to an OpenGL " 19874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "ES context"); 19974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 20074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 20174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 202ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 203ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 204ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 20574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if ((mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) || 20674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis dpy == EGL_NO_DISPLAY) { 207ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis ST_LOGE("updateTexImage: invalid current EGLDisplay"); 20874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 209ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 210ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 21174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if ((mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) || 21274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ctx == EGL_NO_CONTEXT) { 213ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis ST_LOGE("updateTexImage: invalid current EGLContext"); 21474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 215ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 216ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 217ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglDisplay = dpy; 218ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglContext = ctx; 219ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 220b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam BufferQueue::BufferItem item; 221eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 22250c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis // In asynchronous mode the list is guaranteed to be one buffer 22350c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis // deep, while in synchronous mode we use the oldest buffer. 2249fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis err = acquireBufferLocked(&item); 225fbcda930dd8b2823cfeb160fd0131f5897b7522fDaniel Lam if (err == NO_ERROR) { 226eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam int buf = item.mBuf; 227b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 2282c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // we call the rejecter here, in case the caller has a reason to 2292c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // not accept this buffer. this is used by SurfaceFlinger to 2302c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian // reject buffers which have the wrong size 2319fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (rejecter && rejecter->reject(mSlots[buf].mGraphicBuffer, item)) { 2329fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis releaseBufferLocked(buf, dpy, EGL_NO_SYNC_KHR, item.mFence); 2332c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian glBindTexture(mTexTarget, mTexName); 2342c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian return NO_ERROR; 2352c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 2362c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 2379fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis GLint error; 2389fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis while ((error = glGetError()) != GL_NO_ERROR) { 2399fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ST_LOGW("updateTexImage: clearing GL error: %#04x", error); 2408ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 2410eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis 2429fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis EGLImageKHR image = mEglSlots[buf].mEglImage; 2439fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis glBindTexture(mTexTarget, mTexName); 2449fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image); 24574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 2469fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis while ((error = glGetError()) != GL_NO_ERROR) { 2479fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ST_LOGE("updateTexImage: error binding external texture image %p " 2489fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis "(slot %d): %#04x", image, buf, error); 2499fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis err = UNKNOWN_ERROR; 2509fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 251ce7a6c0fc9d75b80da030d1790321e84475f956aJamie Gennis 2529fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (err == NO_ERROR) { 2539fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis err = syncForReleaseLocked(dpy); 2548ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 2559a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 2567e477bfe11f8bb31622353b64e85721df3cf9702Mathias Agopian if (err != NO_ERROR) { 25774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Release the buffer we just acquired. It's not safe to 25874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // release the old buffer, so instead we just drop the new frame. 2599fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis releaseBufferLocked(buf, dpy, EGL_NO_SYNC_KHR, item.mFence); 26074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return err; 26186edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis } 26286edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis 26386edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis ST_LOGV("updateTexImage: (slot=%d buf=%p) -> (slot=%d buf=%p)", 26486edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis mCurrentTexture, 26586edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis mCurrentTextureBuf != NULL ? mCurrentTextureBuf->handle : 0, 2669fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis buf, mSlots[buf].mGraphicBuffer->handle); 2676ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis 2689abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam // release old buffer 26974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 2709fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis status_t status = releaseBufferLocked(mCurrentTexture, dpy, 2719fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[mCurrentTexture].mEglFence, 2729fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mSlots[mCurrentTexture].mFence); 2739fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (status != NO_ERROR && status != BufferQueue::STALE_BUFFER_SLOT) { 2749fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ST_LOGE("updateTexImage: failed to release buffer: %s (%d)", 2759fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis strerror(-status), status); 2769abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam err = status; 2779abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 27874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 279b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 2809a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis // Update the SurfaceTexture state. 281b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mCurrentTexture = buf; 2829fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentTextureBuf = mSlots[buf].mGraphicBuffer; 283eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mCurrentCrop = item.mCrop; 284eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mCurrentTransform = item.mTransform; 285eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mCurrentScalingMode = item.mScalingMode; 286eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mCurrentTimestamp = item.mTimestamp; 287dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall mCurrentFence = item.mFence; 288736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis computeCurrentTransformMatrix(); 289fbcda930dd8b2823cfeb160fd0131f5897b7522fDaniel Lam } else { 290fbcda930dd8b2823cfeb160fd0131f5897b7522fDaniel Lam if (err < 0) { 29145cb2ba1d52d81e20702b62610422fb09aaedeaeJamie Gennis ST_LOGE("updateTexImage failed on acquire %d", err); 292fbcda930dd8b2823cfeb160fd0131f5897b7522fDaniel Lam } 2937a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // We always bind the texture even if we don't update its contents. 294fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis glBindTexture(mTexTarget, mTexName); 295fbcda930dd8b2823cfeb160fd0131f5897b7522fDaniel Lam return OK; 2968ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 29750c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis 2989abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam return err; 2998ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 3008ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 301ef19414bd8b77a26f5751f3845be79025a8263feJesse Hallvoid SurfaceTexture::setReleaseFence(int fenceFd) { 3023d1d09c0c116c42f7d083f87628b5f8377b1f275Jamie Gennis sp<Fence> fence(new Fence(fenceFd)); 30345cb2ba1d52d81e20702b62610422fb09aaedeaeJamie Gennis if (fenceFd == -1 || mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT) 304ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall return; 3059fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (!mSlots[mCurrentTexture].mFence.get()) { 3069fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mSlots[mCurrentTexture].mFence = fence; 307ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } else { 308ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall sp<Fence> mergedFence = Fence::merge( 309ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall String8("SurfaceTexture merged release"), 3109fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mSlots[mCurrentTexture].mFence, fence); 311e7db724bed5d1e5086801df7705d9b1f2a071785Jesse Hall if (!mergedFence.get()) { 31245cb2ba1d52d81e20702b62610422fb09aaedeaeJamie Gennis ST_LOGE("failed to merge release fences"); 313ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall // synchronization is broken, the best we can do is hope fences 314ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall // signal in order so the new fence will act like a union 3159fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mSlots[mCurrentTexture].mFence = fence; 316e7db724bed5d1e5086801df7705d9b1f2a071785Jesse Hall return; 317ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 3189fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mSlots[mCurrentTexture].mFence = mergedFence; 319ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 320ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall} 321ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall 32274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatus_t SurfaceTexture::detachFromContext() { 32374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ATRACE_CALL(); 32474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("detachFromContext"); 32574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis Mutex::Autolock lock(mMutex); 32674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 32774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAbandoned) { 32874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: abandoned SurfaceTexture"); 32974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return NO_INIT; 33074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 33174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 33274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (!mAttached) { 33374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: SurfaceTexture is not attached to a " 33474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "context"); 33574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 33674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 33774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 33874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 33974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 34074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 34174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) { 34274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: invalid current EGLDisplay"); 34374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 34474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 34574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 34674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) { 34774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: invalid current EGLContext"); 34874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 34974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 35074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 35174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (dpy != EGL_NO_DISPLAY && ctx != EGL_NO_CONTEXT) { 35274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis status_t err = syncForReleaseLocked(dpy); 35374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (err != OK) { 35474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return err; 35574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 35674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 35774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glDeleteTextures(1, &mTexName); 35874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 35974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 3609aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis // Because we're giving up the EGLDisplay we need to free all the EGLImages 3619aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis // that are associated with it. They'll be recreated when the 3629aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis // SurfaceTexture gets attached to a new OpenGL ES context (and thus gets a 3639aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis // new EGLDisplay). 3649aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis for (int i =0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 3659fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis EGLImageKHR img = mEglSlots[i].mEglImage; 3665c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis if (img != EGL_NO_IMAGE_KHR) { 3679aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis eglDestroyImageKHR(mEglDisplay, img); 3689fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[i].mEglImage = EGL_NO_IMAGE_KHR; 3699aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis } 3709aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis } 3719aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis 37274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglDisplay = EGL_NO_DISPLAY; 37374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglContext = EGL_NO_CONTEXT; 37474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached = false; 37574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 37674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 37774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 37874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 37974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatus_t SurfaceTexture::attachToContext(GLuint tex) { 38074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ATRACE_CALL(); 38174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("attachToContext"); 38274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis Mutex::Autolock lock(mMutex); 38374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 38474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAbandoned) { 38574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: abandoned SurfaceTexture"); 38674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return NO_INIT; 38774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 38874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 38974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAttached) { 39074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: SurfaceTexture is already attached to a " 39174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "context"); 39274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 39374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 39474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 39574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 39674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 39774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 39874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (dpy == EGL_NO_DISPLAY) { 39974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: invalid current EGLDisplay"); 40074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 40174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 40274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 40374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (ctx == EGL_NO_CONTEXT) { 40474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: invalid current EGLContext"); 40574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 40674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 40774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 40874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // We need to bind the texture regardless of whether there's a current 40974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // buffer. 41074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glBindTexture(mTexTarget, tex); 41174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 41274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mCurrentTextureBuf != NULL) { 4135c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis // The EGLImageKHR that was associated with the slot was destroyed when 4145c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis // the SurfaceTexture was detached from the old context, so we need to 4155c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis // recreate it here. 4165c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis EGLImageKHR image = createImage(dpy, mCurrentTextureBuf); 4175c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis if (image == EGL_NO_IMAGE_KHR) { 4185c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis return UNKNOWN_ERROR; 41974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 42074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 42174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attach the current buffer to the GL texture. 42274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image); 42374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 42474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLint error; 42574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis status_t err = OK; 42674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis while ((error = glGetError()) != GL_NO_ERROR) { 42774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: error binding external texture image %p " 42874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "(slot %d): %#04x", image, mCurrentTexture, error); 42974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis err = UNKNOWN_ERROR; 43074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 43174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 4325c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis // We destroy the EGLImageKHR here because the current buffer may no 4335c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis // longer be associated with one of the buffer slots, so we have 4345c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis // nowhere to to store it. If the buffer is still associated with a 4355c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis // slot then another EGLImageKHR will be created next time that buffer 4365c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis // gets acquired in updateTexImage. 4375c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis eglDestroyImageKHR(dpy, image); 43874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 43974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (err != OK) { 44074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return err; 44174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 44274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 44374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 44474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglDisplay = dpy; 44574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglContext = ctx; 44674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mTexName = tex; 44774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached = true; 44874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 44974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 45074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 45174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 45274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatus_t SurfaceTexture::syncForReleaseLocked(EGLDisplay dpy) { 45374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("syncForReleaseLocked"); 45474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 45574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mUseFenceSync && mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 4569fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis EGLSyncKHR fence = mEglSlots[mCurrentTexture].mEglFence; 45774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (fence != EGL_NO_SYNC_KHR) { 45874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // There is already a fence for the current slot. We need to wait 45974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // on that before replacing it with another fence to ensure that all 46074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // outstanding buffer accesses have completed before the producer 46174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // accesses it. 46274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000); 46374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (result == EGL_FALSE) { 46474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("syncForReleaseLocked: error waiting for previous " 46574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "fence: %#x", eglGetError()); 46674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return UNKNOWN_ERROR; 46774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 46874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("syncForReleaseLocked: timeout waiting for previous " 46974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "fence"); 47074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return TIMED_OUT; 47174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 47274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis eglDestroySyncKHR(dpy, fence); 47374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 47474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 47574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Create a fence for the outstanding accesses in the current OpenGL ES 47674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // context. 47774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL); 47874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (fence == EGL_NO_SYNC_KHR) { 47974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("syncForReleaseLocked: error creating fence: %#x", 48074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis eglGetError()); 48174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return UNKNOWN_ERROR; 48274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 48374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glFlush(); 4849fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[mCurrentTexture].mEglFence = fence; 48574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 48674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 48774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 48874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 48974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 4907a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopianbool SurfaceTexture::isExternalFormat(uint32_t format) 4917a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian{ 4927a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian switch (format) { 4937a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // supported YUV formats 4947a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YV12: 4957a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Legacy/deprecated YUV formats 4967a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_SP: 4977a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCrCb_420_SP: 4987a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_I: 4997a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 5007a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian } 5017a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 5027a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Any OEM format needs to be considered 5037a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian if (format>=0x100 && format<=0x1FF) 5047a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 5057a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 5067a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return false; 5077a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 5087a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 5097a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias AgopianGLenum SurfaceTexture::getCurrentTextureTarget() const { 510fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis return mTexTarget; 5117a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 5127a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 513f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisvoid SurfaceTexture::getTransformMatrix(float mtx[16]) { 514f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis Mutex::Autolock lock(mMutex); 515736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix)); 516736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis} 517736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis 5185c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennisvoid SurfaceTexture::setFilteringEnabled(bool enabled) { 5195c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis Mutex::Autolock lock(mMutex); 5205c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bool needsRecompute = mFilteringEnabled != enabled; 5215c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis mFilteringEnabled = enabled; 5225c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis if (needsRecompute) { 5235c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis computeCurrentTransformMatrix(); 5245c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 5255c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis} 5265c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis 527736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennisvoid SurfaceTexture::computeCurrentTransformMatrix() { 5286ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("computeCurrentTransformMatrix"); 529f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 530a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float xform[16]; 531a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 532a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = mtxIdentity[i]; 533a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 534a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) { 535a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 536a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipH); 537a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 538a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 539a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 540a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 541a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) { 542a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 543a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipV); 544a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 545a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 546a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 547a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 548a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 549a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 550a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxRot90); 551a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 552a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 553a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 554f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis } 555f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 556eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam sp<GraphicBuffer>& buf(mCurrentTextureBuf); 557d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis Rect cropRect = mCurrentCrop; 5585c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis float tx = 0.0f, ty = 0.0f, sx = 1.0f, sy = 1.0f; 5595c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis float bufferWidth = buf->getWidth(); 5605c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis float bufferHeight = buf->getHeight(); 561d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis if (!cropRect.isEmpty()) { 5625c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis float shrinkAmount = 0.0f; 5635c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis if (mFilteringEnabled) { 5645c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // In order to prevent bilinear sampling beyond the edge of the 5655c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // crop rectangle we may need to shrink it by 2 texels in each 5665c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // dimension. Normally this would just need to take 1/2 a texel 5675c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // off each end, but because the chroma channels of YUV420 images 5685c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // are subsampled we may need to shrink the crop region by a whole 5695c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // texel on each side. 5705c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis switch (buf->getPixelFormat()) { 5715c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGBA_8888: 5725c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGBX_8888: 5735c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGB_888: 5745c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGB_565: 5755c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_BGRA_8888: 5765c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGBA_5551: 5775c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGBA_4444: 5785c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // We know there's no subsampling of any channels, so we 5795c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // only need to shrink by a half a pixel. 5805c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis shrinkAmount = 0.5; 5814f9c284de4b9159126f69eb1219c410f66cc872cRomain Guy break; 5829fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 5835c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis default: 5845c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // If we don't recognize the format, we must assume the 5855c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // worst case (that we care about), which is YUV420. 5865c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis shrinkAmount = 1.0; 5879fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis break; 5885c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 5895c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 5905c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis 5915c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // Only shrink the dimensions that are not the size of the buffer. 5925c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis if (cropRect.width() < bufferWidth) { 5935c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis tx = (float(cropRect.left) + shrinkAmount) / bufferWidth; 5945c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis sx = (float(cropRect.width()) - (2.0f * shrinkAmount)) / 5955c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bufferWidth; 5965c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 5975c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis if (cropRect.height() < bufferHeight) { 5985c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis ty = (float(bufferHeight - cropRect.bottom) + shrinkAmount) / 5995c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bufferHeight; 6005c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis sy = (float(cropRect.height()) - (2.0f * shrinkAmount)) / 6015c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bufferHeight; 6025c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 603a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 604f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis float crop[16] = { 605a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis sx, 0, 0, 0, 606a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis 0, sy, 0, 0, 607f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 608d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis tx, ty, 0, 1, 609f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis }; 610f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 611a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float mtxBeforeFlipV[16]; 612a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(mtxBeforeFlipV, crop, xform); 613a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis 614a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // SurfaceFlinger expects the top of its window textures to be at a Y 615a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // coordinate of 0, so SurfaceTexture must behave the same way. We don't 616a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // want to expose this to applications, however, so we must add an 617a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // additional vertical flip to the transform after all the other transforms. 618736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis mtxMul(mCurrentTransformMatrix, mtxFlipV, mtxBeforeFlipV); 619f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 620f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 6211d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvalansecs_t SurfaceTexture::getTimestamp() { 6226ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("getTimestamp"); 6231d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala Mutex::Autolock lock(mMutex); 6241d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala return mCurrentTimestamp; 6251d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala} 6261d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala 6278ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie GennisEGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy, 6288ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis const sp<GraphicBuffer>& graphicBuffer) { 6298ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLClientBuffer cbuf = (EGLClientBuffer)graphicBuffer->getNativeBuffer(); 6308ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLint attrs[] = { 6318ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 6328ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_NONE, 6338ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis }; 6348ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, 6358ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs); 6363cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian if (image == EGL_NO_IMAGE_KHR) { 6373cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian EGLint error = eglGetError(); 638fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("error creating EGLImage: %#x", error); 6398ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 6408ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return image; 6418ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 6428ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 6437a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopiansp<GraphicBuffer> SurfaceTexture::getCurrentBuffer() const { 6447a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 6457a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTextureBuf; 6467a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 6477a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 6487a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias AgopianRect SurfaceTexture::getCurrentCrop() const { 6497a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 650016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 651016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam Rect outCrop = mCurrentCrop; 652016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { 653016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t newWidth = mCurrentCrop.width(); 654016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t newHeight = mCurrentCrop.height(); 655016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 656016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (newWidth * mDefaultHeight > newHeight * mDefaultWidth) { 657016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam newWidth = newHeight * mDefaultWidth / mDefaultHeight; 658016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ST_LOGV("too wide: newWidth = %d", newWidth); 659016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } else if (newWidth * mDefaultHeight < newHeight * mDefaultWidth) { 660016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam newHeight = newWidth * mDefaultHeight / mDefaultWidth; 661016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ST_LOGV("too tall: newHeight = %d", newHeight); 662016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 663016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 664016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The crop is too wide 665016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (newWidth < mCurrentCrop.width()) { 666016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t dw = (newWidth - mCurrentCrop.width())/2; 667016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.left -=dw; 668016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.right += dw; 669016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The crop is too tall 670016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } else if (newHeight < mCurrentCrop.height()) { 671016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t dh = (newHeight - mCurrentCrop.height())/2; 672016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.top -= dh; 673016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.bottom += dh; 674016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 675016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 676016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ST_LOGV("getCurrentCrop final crop [%d,%d,%d,%d]", 677016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.left, outCrop.top, 678016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.right,outCrop.bottom); 679016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 680016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 681016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam return outCrop; 6827a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 6837a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 6847a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopianuint32_t SurfaceTexture::getCurrentTransform() const { 6857a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 6867a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTransform; 6877a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 6887a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 6897734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopianuint32_t SurfaceTexture::getCurrentScalingMode() const { 6907734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian Mutex::Autolock lock(mMutex); 6917734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian return mCurrentScalingMode; 6927734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian} 6937734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian 694dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hallsp<Fence> SurfaceTexture::getCurrentFence() const { 695dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall Mutex::Autolock lock(mMutex); 696dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall return mCurrentFence; 697dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall} 698dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 69959769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennisbool SurfaceTexture::isSynchronousMode() const { 70059769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis Mutex::Autolock lock(mMutex); 701b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->isSynchronousMode(); 70259769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis} 70359769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis 704fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisvoid SurfaceTexture::freeBufferLocked(int slotIndex) { 705fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("freeBufferLocked: slotIndex=%d", slotIndex); 7069abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (slotIndex == mCurrentTexture) { 7079abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; 7089abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 7099fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis EGLImageKHR img = mEglSlots[slotIndex].mEglImage; 7109aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis if (img != EGL_NO_IMAGE_KHR) { 7119aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis ST_LOGV("destroying EGLImage dpy=%p img=%p", mEglDisplay, img); 7129aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis eglDestroyImageKHR(mEglDisplay, img); 713fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 7149fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[slotIndex].mEglImage = EGL_NO_IMAGE_KHR; 7159fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase::freeBufferLocked(slotIndex); 716fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 717fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 7189fea3421ffddf6480f57f55a25936a886043d909Jamie Gennisvoid SurfaceTexture::abandonLocked() { 7199fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ST_LOGV("abandonLocked"); 7209fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentTextureBuf.clear(); 7219fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase::abandonLocked(); 7227b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis} 7237b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 724fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennisvoid SurfaceTexture::setName(const String8& name) { 725eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 726fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis mName = name; 727b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferQueue->setConsumerName(name); 728b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 729b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 730b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setDefaultBufferFormat(uint32_t defaultFormat) { 731b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 732b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setDefaultBufferFormat(defaultFormat); 733b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 734b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 735b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setConsumerUsageBits(uint32_t usage) { 736b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 73785b217668d6840c8e6a109adfb99461313676f8dEino-Ville Talvala usage |= DEFAULT_USAGE_FLAGS; 738b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setConsumerUsageBits(usage); 739b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 740b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 741b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setTransformHint(uint32_t hint) { 742b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 743b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setTransformHint(hint); 744b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 745b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 746b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam// Used for refactoring BufferQueue from SurfaceTexture 747b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam// Should not be in final interface once users of SurfaceTexture are clean up. 748b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setSynchronousMode(bool enabled) { 749b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 750b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setSynchronousMode(enabled); 751b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 752b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 7539fea3421ffddf6480f57f55a25936a886043d909Jamie Gennisvoid SurfaceTexture::dumpLocked(String8& result, const char* prefix, 7549fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis char* buffer, size_t size) const 75568c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian{ 7569fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis snprintf(buffer, size, 7579fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis "%smTexName=%d mCurrentTexture=%d\n" 7589fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis "%smCurrentCrop=[%d,%d,%d,%d] mCurrentTransform=%#x\n", 7599fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis prefix, mTexName, mCurrentTexture, prefix, mCurrentCrop.left, 7609fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom, 7619fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentTransform); 76268c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian result.append(buffer); 76368c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 7649fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase::dumpLocked(result, prefix, buffer, size); 76568c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian} 76668c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 767f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]) { 768f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3]; 769f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3]; 770f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3]; 771f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3]; 772f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 773f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7]; 774f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7]; 775f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7]; 776f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7]; 777f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 778f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11]; 779f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11]; 780f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11]; 781f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11]; 782f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 783f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15]; 784f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15]; 785f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15]; 786f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15]; 787f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 788f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 7898ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis}; // namespace android 790