GLConsumer.cpp revision 74bed55fff0132be319bcd1703970516ae28b3a9
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 297a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian#include <hardware/hardware.h> 307a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 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 101eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam// Get an ID that's unique within this process. 102eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lamstatic int32_t createProcessUniqueId() { 103eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam static volatile int32_t globalCounter = 0; 104eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam return android_atomic_inc(&globalCounter); 105eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam} 106fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis 107fb1b5a2f333800574b0da435d1200cf9b13d723fJamie GennisSurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode, 108b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue) : 1091d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTransform(0), 1101d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTimestamp(0), 111b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mTexName(tex), 11286edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis#ifdef USE_FENCE_SYNC 11386edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis mUseFenceSync(useFenceSync), 11486edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis#else 11586edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis mUseFenceSync(false), 11686edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis#endif 117eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mTexTarget(texTarget), 118ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglDisplay(EGL_NO_DISPLAY), 119ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglContext(EGL_NO_CONTEXT), 120eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mAbandoned(false), 12174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), 12274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached(true) 1236b091c53000c843211c218ce40287a7edca9bc63Daniel Lam{ 124eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // Choose a name using the PID and a process-unique ID. 125eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId()); 1266ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("SurfaceTexture"); 127b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam if (bufferQueue == 0) { 128b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam ST_LOGV("Creating a new BufferQueue"); 129b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferQueue = new BufferQueue(allowSynchronousMode); 130b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam } 131b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam else { 132b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferQueue = bufferQueue; 133b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam } 134b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 135fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis memcpy(mCurrentTransformMatrix, mtxIdentity, 136fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis sizeof(mCurrentTransformMatrix)); 137fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 138fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // Note that we can't create an sp<...>(this) in a ctor that will not keep a 139fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // reference once the ctor ends, as that would cause the refcount of 'this' 140fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // dropping to 0 at the end of the ctor. Since all we need is a wp<...> 141fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // that's what we create. 142fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis wp<BufferQueue::ConsumerListener> listener; 143fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis sp<BufferQueue::ConsumerListener> proxy; 144fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener = static_cast<BufferQueue::ConsumerListener*>(this); 145fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis proxy = new BufferQueue::ProxyConsumerListener(listener); 146fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 147fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis status_t err = mBufferQueue->consumerConnect(proxy); 148fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (err != NO_ERROR) { 149fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGE("SurfaceTexture: error connecting to BufferQueue: %s (%d)", 150fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis strerror(-err), err); 151fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } else { 152fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mBufferQueue->setConsumerName(mName); 153fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 1548ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 1558ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 1568ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie GennisSurfaceTexture::~SurfaceTexture() { 1576ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("~SurfaceTexture"); 158b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 159eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam abandon(); 1608ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 1618ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 1628072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopianstatus_t SurfaceTexture::setBufferCountServer(int bufferCount) { 1638072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian Mutex::Autolock lock(mMutex); 164b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setBufferCountServer(bufferCount); 1658072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian} 1668072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 1678ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 168a5c75c01620179ce00812354778a29a80d76e71fMathias Agopianstatus_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h) 169a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian{ 170b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 171b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setDefaultBufferSize(w, h); 172a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian} 173a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian 1748ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennisstatus_t SurfaceTexture::updateTexImage() { 1751c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 1766ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("updateTexImage"); 1778ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis Mutex::Autolock lock(mMutex); 1788ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 179e47498f8f258967ff62d070f08ff2dadd4ae2b56Mathias Agopian if (mAbandoned) { 18074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("updateTexImage: SurfaceTexture is abandoned!"); 1818e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian return NO_INIT; 182e47498f8f258967ff62d070f08ff2dadd4ae2b56Mathias Agopian } 183e47498f8f258967ff62d070f08ff2dadd4ae2b56Mathias Agopian 18474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (!mAttached) { 18574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("updateTexImage: SurfaceTexture is not attached to an OpenGL " 18674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "ES context"); 18774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 18874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 18974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 190ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 191ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 192ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 19374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if ((mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) || 19474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis dpy == EGL_NO_DISPLAY) { 195ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis ST_LOGE("updateTexImage: invalid current EGLDisplay"); 19674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 197ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 198ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 19974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if ((mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) || 20074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ctx == EGL_NO_CONTEXT) { 201ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis ST_LOGE("updateTexImage: invalid current EGLContext"); 20274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 203ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 204ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 205ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglDisplay = dpy; 206ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglContext = ctx; 207ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 208b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam BufferQueue::BufferItem item; 209eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 21050c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis // In asynchronous mode the list is guaranteed to be one buffer 21150c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis // deep, while in synchronous mode we use the oldest buffer. 212fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mBufferQueue->acquireBuffer(&item) == NO_ERROR) { 213eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam int buf = item.mBuf; 214eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // This buffer was newly allocated, so we need to clean up on our side 215eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (item.mGraphicBuffer != NULL) { 216eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[buf].mGraphicBuffer = 0; 217eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (mEGLSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) { 218ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis eglDestroyImageKHR(dpy, mEGLSlots[buf].mEglImage); 219eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[buf].mEglImage = EGL_NO_IMAGE_KHR; 220eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 221eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[buf].mGraphicBuffer = item.mGraphicBuffer; 222eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 223b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 224f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis // Update the GL texture object. 225eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam EGLImageKHR image = mEGLSlots[buf].mEglImage; 2268ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis if (image == EGL_NO_IMAGE_KHR) { 227eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (item.mGraphicBuffer == 0) { 22874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("updateTexImage: buffer at slot %d is null", buf); 2298e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian return BAD_VALUE; 230e47498f8f258967ff62d070f08ff2dadd4ae2b56Mathias Agopian } 231eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam image = createImage(dpy, item.mGraphicBuffer); 232eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[buf].mEglImage = image; 2333cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian if (image == EGL_NO_IMAGE_KHR) { 2343cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian // NOTE: if dpy was invalid, createImage() is guaranteed to 2353cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian // fail. so we'd end up here. 23674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return UNKNOWN_ERROR; 2373cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian } 2388ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 2390eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis 2400eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis GLint error; 2410eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis while ((error = glGetError()) != GL_NO_ERROR) { 242fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGW("updateTexImage: clearing GL error: %#04x", error); 2430eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis } 2447a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 245fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis glBindTexture(mTexTarget, mTexName); 246fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image); 2477a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 24874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis status_t err = OK; 2490eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis while ((error = glGetError()) != GL_NO_ERROR) { 25074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("updateTexImage: error binding external texture image %p " 25174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "(slot %d): %#04x", image, buf, error); 25274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis err = UNKNOWN_ERROR; 2530eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis } 25474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 25574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (err == OK) { 25674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis err = syncForReleaseLocked(dpy); 2578ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 2589a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 25974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (err != OK) { 26074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Release the buffer we just acquired. It's not safe to 26174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // release the old buffer, so instead we just drop the new frame. 26274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mBufferQueue->releaseBuffer(buf, dpy, mEGLSlots[buf].mFence); 26374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEGLSlots[buf].mFence = EGL_NO_SYNC_KHR; 26474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return err; 26586edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis } 26686edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis 26786edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis ST_LOGV("updateTexImage: (slot=%d buf=%p) -> (slot=%d buf=%p)", 26886edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis mCurrentTexture, 26986edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis mCurrentTextureBuf != NULL ? mCurrentTextureBuf->handle : 0, 270eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buf, item.mGraphicBuffer != NULL ? item.mGraphicBuffer->handle : 0); 2716ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis 27274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Release the old buffer 27374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 27474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mBufferQueue->releaseBuffer(mCurrentTexture, dpy, 27574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEGLSlots[mCurrentTexture].mFence); 27674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEGLSlots[mCurrentTexture].mFence = EGL_NO_SYNC_KHR; 27774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 278b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 2799a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis // Update the SurfaceTexture state. 280b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mCurrentTexture = buf; 281eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mCurrentTextureBuf = mEGLSlots[buf].mGraphicBuffer; 282eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mCurrentCrop = item.mCrop; 283eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mCurrentTransform = item.mTransform; 284eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mCurrentScalingMode = item.mScalingMode; 285eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mCurrentTimestamp = item.mTimestamp; 286736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis computeCurrentTransformMatrix(); 2877a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian } else { 2887a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // We always bind the texture even if we don't update its contents. 289fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis glBindTexture(mTexTarget, mTexName); 2908ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 29150c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis 2928ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return OK; 2938ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 2948ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 29574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatus_t SurfaceTexture::detachFromContext() { 29674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ATRACE_CALL(); 29774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("detachFromContext"); 29874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis Mutex::Autolock lock(mMutex); 29974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 30074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAbandoned) { 30174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: abandoned SurfaceTexture"); 30274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return NO_INIT; 30374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 30474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 30574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (!mAttached) { 30674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: SurfaceTexture is not attached to a " 30774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "context"); 30874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 30974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 31074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 31174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 31274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 31374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 31474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) { 31574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: invalid current EGLDisplay"); 31674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 31774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 31874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 31974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) { 32074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: invalid current EGLContext"); 32174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 32274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 32374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 32474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (dpy != EGL_NO_DISPLAY && ctx != EGL_NO_CONTEXT) { 32574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis status_t err = syncForReleaseLocked(dpy); 32674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (err != OK) { 32774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return err; 32874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 32974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 33074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glDeleteTextures(1, &mTexName); 33174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 33274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 33374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglDisplay = EGL_NO_DISPLAY; 33474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglContext = EGL_NO_CONTEXT; 33574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached = false; 33674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 33774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 33874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 33974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 34074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatus_t SurfaceTexture::attachToContext(GLuint tex) { 34174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ATRACE_CALL(); 34274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("attachToContext"); 34374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis Mutex::Autolock lock(mMutex); 34474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 34574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAbandoned) { 34674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: abandoned SurfaceTexture"); 34774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return NO_INIT; 34874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 34974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 35074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAttached) { 35174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: SurfaceTexture is already attached to a " 35274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "context"); 35374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 35474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 35574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 35674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 35774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 35874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 35974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (dpy == EGL_NO_DISPLAY) { 36074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: invalid current EGLDisplay"); 36174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 36274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 36374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 36474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (ctx == EGL_NO_CONTEXT) { 36574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: invalid current EGLContext"); 36674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 36774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 36874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 36974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // We need to bind the texture regardless of whether there's a current 37074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // buffer. 37174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glBindTexture(mTexTarget, tex); 37274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 37374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mCurrentTextureBuf != NULL) { 37474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // If the current buffer is no longer associated with a slot, then it 37574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // doesn't have an EGLImage. In that case we create one now, but we also 37674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // destroy it once we've used it to attach the buffer to the OpenGL ES 37774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // texture. 37874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis bool imageNeedsDestroy = false; 37974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLImageKHR image = EGL_NO_IMAGE_KHR; 38074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 38174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis image = mEGLSlots[mCurrentTexture].mEglImage; 38274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis imageNeedsDestroy = false; 38374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } else { 38474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis image = createImage(dpy, mCurrentTextureBuf); 38574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (image == EGL_NO_IMAGE_KHR) { 38674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return UNKNOWN_ERROR; 38774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 38874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis imageNeedsDestroy = true; 38974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 39074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 39174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Attach the current buffer to the GL texture. 39274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image); 39374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 39474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis GLint error; 39574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis status_t err = OK; 39674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis while ((error = glGetError()) != GL_NO_ERROR) { 39774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: error binding external texture image %p " 39874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "(slot %d): %#04x", image, mCurrentTexture, error); 39974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis err = UNKNOWN_ERROR; 40074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 40174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 40274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (imageNeedsDestroy) { 40374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis eglDestroyImageKHR(dpy, image); 40474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 40574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 40674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (err != OK) { 40774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return err; 40874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 40974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 41074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 41174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglDisplay = dpy; 41274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglContext = ctx; 41374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mTexName = tex; 41474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached = true; 41574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 41674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 41774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 41874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 41974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatus_t SurfaceTexture::syncForReleaseLocked(EGLDisplay dpy) { 42074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("syncForReleaseLocked"); 42174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 42274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mUseFenceSync && mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 42374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLSyncKHR fence = mEGLSlots[mCurrentTexture].mFence; 42474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (fence != EGL_NO_SYNC_KHR) { 42574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // There is already a fence for the current slot. We need to wait 42674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // on that before replacing it with another fence to ensure that all 42774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // outstanding buffer accesses have completed before the producer 42874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // accesses it. 42974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000); 43074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (result == EGL_FALSE) { 43174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("syncForReleaseLocked: error waiting for previous " 43274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "fence: %#x", eglGetError()); 43374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return UNKNOWN_ERROR; 43474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 43574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("syncForReleaseLocked: timeout waiting for previous " 43674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "fence"); 43774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return TIMED_OUT; 43874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 43974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis eglDestroySyncKHR(dpy, fence); 44074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 44174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 44274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // Create a fence for the outstanding accesses in the current OpenGL ES 44374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // context. 44474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL); 44574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (fence == EGL_NO_SYNC_KHR) { 44674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("syncForReleaseLocked: error creating fence: %#x", 44774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis eglGetError()); 44874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return UNKNOWN_ERROR; 44974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 45074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glFlush(); 45174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEGLSlots[mCurrentTexture].mFence = fence; 45274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 45374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 45474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 45574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 45674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 4577a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopianbool SurfaceTexture::isExternalFormat(uint32_t format) 4587a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian{ 4597a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian switch (format) { 4607a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // supported YUV formats 4617a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YV12: 4627a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Legacy/deprecated YUV formats 4637a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_SP: 4647a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCrCb_420_SP: 4657a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_I: 4667a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 4677a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian } 4687a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 4697a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Any OEM format needs to be considered 4707a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian if (format>=0x100 && format<=0x1FF) 4717a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 4727a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 4737a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return false; 4747a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 4757a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 4767a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias AgopianGLenum SurfaceTexture::getCurrentTextureTarget() const { 477fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis return mTexTarget; 4787a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 4797a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 480f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisvoid SurfaceTexture::getTransformMatrix(float mtx[16]) { 481f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis Mutex::Autolock lock(mMutex); 482736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix)); 483736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis} 484736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis 485736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennisvoid SurfaceTexture::computeCurrentTransformMatrix() { 4866ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("computeCurrentTransformMatrix"); 487f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 488a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float xform[16]; 489a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 490a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = mtxIdentity[i]; 491a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 492a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) { 493a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 494a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipH); 495a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 496a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 497a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 498a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 499a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) { 500a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 501a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipV); 502a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 503a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 504a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 505a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 506a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 507a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 508a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxRot90); 509a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 510a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 511a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 512f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis } 513f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 514eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam sp<GraphicBuffer>& buf(mCurrentTextureBuf); 515a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float tx, ty, sx, sy; 516a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (!mCurrentCrop.isEmpty()) { 517d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // In order to prevent bilinear sampling at the of the crop rectangle we 518d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // may need to shrink it by 2 texels in each direction. Normally this 519d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // would just need to take 1/2 a texel off each end, but because the 520d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // chroma channels will likely be subsampled we need to chop off a whole 521d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // texel. This will cause artifacts if someone does nearest sampling 522d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // with 1:1 pixel:texel ratio, but it's impossible to simultaneously 523d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // accomodate the bilinear and nearest sampling uses. 524d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // 525d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // If nearest sampling turns out to be a desirable usage of these 526d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // textures then we could add the ability to switch a SurfaceTexture to 527d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // nearest-mode. Preferably, however, the image producers (video 528d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // decoder, camera, etc.) would simply not use a crop rectangle (or at 529d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // least not tell the framework about it) so that the GPU can do the 530d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // correct edge behavior. 531d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis int xshrink = 0, yshrink = 0; 532d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis if (mCurrentCrop.left > 0) { 533d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis tx = float(mCurrentCrop.left + 1) / float(buf->getWidth()); 534d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis xshrink++; 535d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } else { 536d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis tx = 0.0f; 537d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 538a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian if (mCurrentCrop.right < int32_t(buf->getWidth())) { 539d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis xshrink++; 540d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 541a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian if (mCurrentCrop.bottom < int32_t(buf->getHeight())) { 542d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis ty = (float(buf->getHeight() - mCurrentCrop.bottom) + 1.0f) / 543d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis float(buf->getHeight()); 544d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis yshrink++; 545d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } else { 546d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis ty = 0.0f; 547d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 548d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis if (mCurrentCrop.top > 0) { 549d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis yshrink++; 550d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 551d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis sx = float(mCurrentCrop.width() - xshrink) / float(buf->getWidth()); 552d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis sy = float(mCurrentCrop.height() - yshrink) / float(buf->getHeight()); 553a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } else { 554a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis tx = 0.0f; 555a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis ty = 0.0f; 556a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis sx = 1.0f; 557a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis sy = 1.0f; 558a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 559f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis float crop[16] = { 560a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis sx, 0, 0, 0, 561a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis 0, sy, 0, 0, 562f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 563d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis tx, ty, 0, 1, 564f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis }; 565f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 566a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float mtxBeforeFlipV[16]; 567a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(mtxBeforeFlipV, crop, xform); 568a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis 569a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // SurfaceFlinger expects the top of its window textures to be at a Y 570a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // coordinate of 0, so SurfaceTexture must behave the same way. We don't 571a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // want to expose this to applications, however, so we must add an 572a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // additional vertical flip to the transform after all the other transforms. 573736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis mtxMul(mCurrentTransformMatrix, mtxFlipV, mtxBeforeFlipV); 574f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 575f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 5761d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvalansecs_t SurfaceTexture::getTimestamp() { 5776ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("getTimestamp"); 5781d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala Mutex::Autolock lock(mMutex); 5791d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala return mCurrentTimestamp; 5801d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala} 5811d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala 582c4d4aeab52435c177ded6abdd578fec8191f0f5dJamie Gennisvoid SurfaceTexture::setFrameAvailableListener( 583292a31a4c2ae2f6faf134e8e4a726583017dad06Pannag Sanketi const sp<FrameAvailableListener>& listener) { 5846ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("setFrameAvailableListener"); 585c4d4aeab52435c177ded6abdd578fec8191f0f5dJamie Gennis Mutex::Autolock lock(mMutex); 586fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mFrameAvailableListener = listener; 587c4d4aeab52435c177ded6abdd578fec8191f0f5dJamie Gennis} 588c4d4aeab52435c177ded6abdd578fec8191f0f5dJamie Gennis 5898ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie GennisEGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy, 5908ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis const sp<GraphicBuffer>& graphicBuffer) { 5918ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLClientBuffer cbuf = (EGLClientBuffer)graphicBuffer->getNativeBuffer(); 5928ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLint attrs[] = { 5938ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 5948ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_NONE, 5958ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis }; 5968ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, 5978ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs); 5983cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian if (image == EGL_NO_IMAGE_KHR) { 5993cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian EGLint error = eglGetError(); 600fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("error creating EGLImage: %#x", error); 6018ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 6028ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return image; 6038ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 6048ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 6057a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopiansp<GraphicBuffer> SurfaceTexture::getCurrentBuffer() const { 6067a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 6077a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTextureBuf; 6087a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 6097a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 6107a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias AgopianRect SurfaceTexture::getCurrentCrop() const { 6117a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 6127a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentCrop; 6137a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 6147a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 6157a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopianuint32_t SurfaceTexture::getCurrentTransform() const { 6167a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 6177a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTransform; 6187a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 6197a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 6207734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopianuint32_t SurfaceTexture::getCurrentScalingMode() const { 6217734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian Mutex::Autolock lock(mMutex); 6227734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian return mCurrentScalingMode; 6237734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian} 6247734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian 62559769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennisbool SurfaceTexture::isSynchronousMode() const { 62659769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis Mutex::Autolock lock(mMutex); 627b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->isSynchronousMode(); 62859769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis} 62959769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis 630fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisvoid SurfaceTexture::freeBufferLocked(int slotIndex) { 631fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("freeBufferLocked: slotIndex=%d", slotIndex); 632fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mEGLSlots[slotIndex].mGraphicBuffer = 0; 633fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mEGLSlots[slotIndex].mEglImage != EGL_NO_IMAGE_KHR) { 634fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis EGLImageKHR img = mEGLSlots[slotIndex].mEglImage; 635fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (img != EGL_NO_IMAGE_KHR) { 636ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis eglDestroyImageKHR(mEglDisplay, img); 637fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 638fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mEGLSlots[slotIndex].mEglImage = EGL_NO_IMAGE_KHR; 639fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 640fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 641fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 6427b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennisvoid SurfaceTexture::abandon() { 643fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("abandon"); 6447b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis Mutex::Autolock lock(mMutex); 645fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 646fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (!mAbandoned) { 647fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mAbandoned = true; 648fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mCurrentTextureBuf.clear(); 649fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 650fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // destroy all egl buffers 651fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis for (int i =0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 652fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis freeBufferLocked(i); 653eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 654eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 655fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // disconnect from the BufferQueue 656fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mBufferQueue->consumerDisconnect(); 657fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mBufferQueue.clear(); 658fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 6597b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis} 6607b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 661fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennisvoid SurfaceTexture::setName(const String8& name) { 662eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 663fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis mName = name; 664b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferQueue->setConsumerName(name); 665b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 666b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 667b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setDefaultBufferFormat(uint32_t defaultFormat) { 668b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 669b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setDefaultBufferFormat(defaultFormat); 670b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 671b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 672b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setConsumerUsageBits(uint32_t usage) { 673b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 674b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setConsumerUsageBits(usage); 675b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 676b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 677b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setTransformHint(uint32_t hint) { 678b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 679b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setTransformHint(hint); 680b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 681b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 682b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam// Used for refactoring BufferQueue from SurfaceTexture 683b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam// Should not be in final interface once users of SurfaceTexture are clean up. 684b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setSynchronousMode(bool enabled) { 685b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 686b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setSynchronousMode(enabled); 687b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 688b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 689b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam// Used for refactoring, should not be in final interface 690b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamsp<BufferQueue> SurfaceTexture::getBufferQueue() const { 691b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 692b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue; 693b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 694b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 695b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam// Used for refactoring, should not be in final interface 696b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setBufferCount(int bufferCount) { 697b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 698b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setBufferCount(bufferCount); 699b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 700b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 701b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam// Used for refactoring, should not be in final interface 702b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::connect(int api, 703b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) { 704b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 705b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->connect(api, outWidth, outHeight, outTransform); 706fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis} 707fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis 708fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisvoid SurfaceTexture::onFrameAvailable() { 709fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("onFrameAvailable"); 710fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 711fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis sp<FrameAvailableListener> listener; 712fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis { // scope for the lock 713fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis Mutex::Autolock lock(mMutex); 714fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener = mFrameAvailableListener; 715fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 716fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 717fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (listener != NULL) { 718fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("actually calling onFrameAvailable"); 719fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis listener->onFrameAvailable(); 720fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 721fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 722fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 723fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisvoid SurfaceTexture::onBuffersReleased() { 724fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("onBuffersReleased"); 725fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 726fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis Mutex::Autolock lock(mMutex); 727fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 728fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mAbandoned) { 729fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis // Nothing to do if we're already abandoned. 730fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis return; 731fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 732fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 733fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis uint32_t mask = 0; 734fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mBufferQueue->getReleasedBuffers(&mask); 735fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 736fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (mask & (1 << i)) { 737fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis freeBufferLocked(i); 738fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 739fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 740f71c4ae136f7749b9dfdaa2dd64d771868eeeb2dDaniel Lam 741f71c4ae136f7749b9dfdaa2dd64d771868eeeb2dDaniel Lam mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; 742fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 743fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 74468c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopianvoid SurfaceTexture::dump(String8& result) const 74568c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian{ 74668c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian char buffer[1024]; 74768c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian dump(result, "", buffer, 1024); 74868c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian} 74968c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 75068c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopianvoid SurfaceTexture::dump(String8& result, const char* prefix, 75168c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian char* buffer, size_t SIZE) const 75268c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian{ 75368c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian Mutex::Autolock _l(mMutex); 754fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis snprintf(buffer, SIZE, "%smTexName=%d, mAbandoned=%d\n", prefix, mTexName, 755fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis int(mAbandoned)); 75668c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian result.append(buffer); 75768c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 75868c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian snprintf(buffer, SIZE, 759fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis "%snext : {crop=[%d,%d,%d,%d], transform=0x%02x, current=%d}\n", 760fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis prefix, mCurrentCrop.left, 76168c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom, 762eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mCurrentTransform, mCurrentTexture 76368c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian ); 76468c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian result.append(buffer); 76568c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 766fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis if (!mAbandoned) { 767fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis mBufferQueue->dump(result, prefix, buffer, SIZE); 768fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 76968c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian} 77068c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 771f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]) { 772f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3]; 773f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3]; 774f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3]; 775f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3]; 776f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 777f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7]; 778f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7]; 779f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7]; 780f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7]; 781f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 782f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11]; 783f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11]; 784f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11]; 785f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11]; 786f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 787f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15]; 788f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15]; 789f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15]; 790f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15]; 791f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 792f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 7938ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis}; // namespace android 794