GLConsumer.cpp revision bf974abe92f7495529916fe0f483f3b56e7c30e3
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 4201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis// This compile option makes SurfaceTexture use the 4301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis// EGL_ANDROID_native_fence_sync extension to create Android native fences to 4401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis// signal when all GLES reads for a given buffer have completed. It is not 4501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis// compatible with using the EGL_KHR_fence_sync extension for the same 4601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis// purpose. 4701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis#ifdef USE_NATIVE_FENCE_SYNC 4801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis#ifdef USE_FENCE_SYNC 4901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis#error "USE_NATIVE_FENCE_SYNC and USE_FENCE_SYNC are incompatible" 5001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis#endif 5161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennisstatic const bool useNativeFenceSync = true; 5201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis#else 5361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennisstatic const bool useNativeFenceSync = false; 5461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis#endif 5561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 5661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis// This compile option makes SurfaceTexture use the EGL_ANDROID_sync_wait 5761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis// extension to insert server-side waits into the GLES command stream. This 5861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis// feature requires the EGL_ANDROID_native_fence_sync and 5961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis// EGL_ANDROID_wait_sync extensions. 6061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis#ifdef USE_WAIT_SYNC 6161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennisstatic const bool useWaitSync = true; 6261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis#else 6361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennisstatic const bool useWaitSync = false; 6401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis#endif 6501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis 66fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis// Macros for including the SurfaceTexture name in log messages 676807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block#define ST_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__) 689d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block#define ST_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__) 69a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block#define ST_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__) 7032397c1cd3327905173b36baa6fd1c579bc328ffSteve Block#define ST_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__) 71e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block#define ST_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__) 7229b5762efc359022168e5099c1d17925444d3147Mathias Agopian 738ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennisnamespace android { 748ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 75f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis// Transform matrices 76f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxIdentity[16] = { 77f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 0, 78f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 79f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 80f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 0, 1, 81f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 82f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxFlipH[16] = { 83f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis -1, 0, 0, 0, 84f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 85f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 86f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 1, 87f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 88f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxFlipV[16] = { 89f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 0, 90f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, -1, 0, 0, 91f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 92f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 1, 93f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 94f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxRot90[16] = { 95f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 96f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis -1, 0, 0, 0, 97f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 98f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 1, 99f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 100f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxRot180[16] = { 101f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis -1, 0, 0, 0, 102f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, -1, 0, 0, 103f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 104f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 1, 0, 1, 105f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 106f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxRot270[16] = { 107f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, -1, 0, 0, 108f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 0, 109f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 110f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 1, 111f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 112f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 113f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]); 114f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 115fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis 116fb1b5a2f333800574b0da435d1200cf9b13d723fJamie GennisSurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode, 117b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue) : 1189fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase(bufferQueue == 0 ? new BufferQueue(allowSynchronousMode) : bufferQueue), 1191d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTransform(0), 1201d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTimestamp(0), 1215c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis mFilteringEnabled(true), 122b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mTexName(tex), 12386edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis#ifdef USE_FENCE_SYNC 12486edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis mUseFenceSync(useFenceSync), 12586edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis#else 12686edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis mUseFenceSync(false), 12786edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis#endif 128eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mTexTarget(texTarget), 129ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglDisplay(EGL_NO_DISPLAY), 130ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglContext(EGL_NO_CONTEXT), 13174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), 13274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached(true) 1336b091c53000c843211c218ce40287a7edca9bc63Daniel Lam{ 1346ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("SurfaceTexture"); 135b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 136fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis memcpy(mCurrentTransformMatrix, mtxIdentity, 137fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis sizeof(mCurrentTransformMatrix)); 138fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1399fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mBufferQueue->setConsumerUsageBits(DEFAULT_USAGE_FLAGS); 1408ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 1418ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 14231a353da225af5329735451c761b430d82dfda1bJamie Gennisstatus_t SurfaceTexture::setDefaultMaxBufferCount(int bufferCount) { 1438072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian Mutex::Autolock lock(mMutex); 14431a353da225af5329735451c761b430d82dfda1bJamie Gennis return mBufferQueue->setDefaultMaxBufferCount(bufferCount); 1458072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian} 1468072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 1478ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 148a5c75c01620179ce00812354778a29a80d76e71fMathias Agopianstatus_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h) 149a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian{ 150b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 151016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam mDefaultWidth = w; 152016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam mDefaultHeight = h; 153b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setDefaultBufferSize(w, h); 154a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian} 155a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian 1568ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennisstatus_t SurfaceTexture::updateTexImage() { 157bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ATRACE_CALL(); 158bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGV("updateTexImage"); 159bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden Mutex::Autolock lock(mMutex); 160bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 161bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mAbandoned) { 162bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("updateTexImage: SurfaceTexture is abandoned!"); 163bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return NO_INIT; 164bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 165bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 166bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Make sure the EGL state is the same as in previous calls. 167bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = checkAndUpdateEglStateLocked(); 168bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 169bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 170bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 171bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 172bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden BufferQueue::BufferItem item; 173bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 174bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Acquire the next buffer. 175bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // In asynchronous mode the list is guaranteed to be one buffer 176bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // deep, while in synchronous mode we use the oldest buffer. 177bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = acquireBufferLocked(&item); 178bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 179bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 180bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We always bind the texture even if we don't update its contents. 181bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGV("updateTexImage: no buffers were available"); 182bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 183bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = NO_ERROR; 184bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } else { 185bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("updateTexImage: acquire failed: %s (%d)", 186bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden strerror(-err), err); 187bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 188bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 189bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 190bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 191bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Release the previous buffer. 192bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = releaseAndUpdateLocked(item); 193bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 194bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We always bind the texture. 195bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 196bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 197bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 198bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 199bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Bind the new buffer to the GL texture. 200bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = bindTextureImage(); 201bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 202bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 203bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 204bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 205bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Wait for the new buffer to be ready. 206bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return doGLFenceWaitLocked(); 2072c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian} 2082c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 2099fea3421ffddf6480f57f55a25936a886043d909Jamie Gennisstatus_t SurfaceTexture::acquireBufferLocked(BufferQueue::BufferItem *item) { 2109fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis status_t err = ConsumerBase::acquireBufferLocked(item); 2119fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (err != NO_ERROR) { 2129fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return err; 2139fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 2149fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 2159fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis int slot = item->mBuf; 2169fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (item->mGraphicBuffer != NULL) { 217bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // This buffer has not been acquired before, so we must assume 218bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // that any EGLImage in mEglSlots is stale. 2199fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (mEglSlots[slot].mEglImage != EGL_NO_IMAGE_KHR) { 220bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (!eglDestroyImageKHR(mEglDisplay, mEglSlots[slot].mEglImage)) { 221bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGW("acquireBufferLocked: eglDestroyImageKHR failed for slot=%d", 222bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden slot); 223bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // keep going 224bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 2259fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[slot].mEglImage = EGL_NO_IMAGE_KHR; 2269fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 2279fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 2289fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 2299fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return NO_ERROR; 2309fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis} 2319fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 2329fea3421ffddf6480f57f55a25936a886043d909Jamie Gennisstatus_t SurfaceTexture::releaseBufferLocked(int buf, EGLDisplay display, 233b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis EGLSyncKHR eglFence) { 234bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = ConsumerBase::releaseBufferLocked(buf, display, eglFence); 2359fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 236d1b330de416adff0d178a5cb7271419d9ed7a89aJamie Gennis mEglSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 2379fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 2389fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return err; 2399fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis} 2409fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 241bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFaddenstatus_t SurfaceTexture::releaseAndUpdateLocked(const BufferQueue::BufferItem& item) 242bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden{ 2439abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam status_t err = NO_ERROR; 2449abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 24574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (!mAttached) { 246bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("releaseAndUpdate: SurfaceTexture is not attached to an OpenGL " 24774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "ES context"); 24874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 24974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 25074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 251bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Confirm state. 252bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = checkAndUpdateEglStateLocked(); 253bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 254bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 255ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 256ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 257bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden int buf = item.mBuf; 258bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 259bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // If the mEglSlot entry is empty, create an EGLImage for the gralloc 260bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // buffer currently in the slot in ConsumerBase. 261bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // 262bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We may have to do this even when item.mGraphicBuffer == NULL (which 263bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // means the buffer was previously acquired), if we destroyed the 264bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // EGLImage when detaching from a context but the buffer has not been 265bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // re-allocated. 266bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mEglSlots[buf].mEglImage == EGL_NO_IMAGE_KHR) { 267bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLImageKHR image = createImage(mEglDisplay, mSlots[buf].mGraphicBuffer); 268bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (image == EGL_NO_IMAGE_KHR) { 269bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGW("releaseAndUpdate: unable to createImage on display=%p slot=%d", 270bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglDisplay, buf); 271bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return UNKNOWN_ERROR; 272bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 273bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglSlots[buf].mEglImage = image; 274ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 275ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 276bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Do whatever sync ops we need to do before releasing the old slot. 277bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = syncForReleaseLocked(mEglDisplay); 278bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 279bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Release the buffer we just acquired. It's not safe to 280bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // release the old buffer, so instead we just drop the new frame. 281bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden releaseBufferLocked(buf, mEglDisplay, EGL_NO_SYNC_KHR); 282bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 283bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 284ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 285bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGV("releaseAndUpdate: (slot=%d buf=%p) -> (slot=%d buf=%p)", 286bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTexture, 287bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTextureBuf != NULL ? mCurrentTextureBuf->handle : 0, 288bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden buf, mSlots[buf].mGraphicBuffer->handle); 289eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 290bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // release old buffer 291bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 292bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t status = releaseBufferLocked(mCurrentTexture, mEglDisplay, 293bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglSlots[mCurrentTexture].mEglFence); 294bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (status != NO_ERROR && status != BufferQueue::STALE_BUFFER_SLOT) { 295bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("releaseAndUpdate: failed to release buffer: %s (%d)", 296bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden strerror(-status), status); 297bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = status; 298bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // keep going, with error raised [?] 2992c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 300bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 3012c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 302bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Update the SurfaceTexture state. 303bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTexture = buf; 304bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTextureBuf = mSlots[buf].mGraphicBuffer; 305bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentCrop = item.mCrop; 306bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTransform = item.mTransform; 307bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentScalingMode = item.mScalingMode; 308bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTimestamp = item.mTimestamp; 309bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentFence = item.mFence; 310bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 311bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden computeCurrentTransformMatrixLocked(); 312bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 313bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 314bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 315bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 316bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFaddenstatus_t SurfaceTexture::bindTextureImage() { 317bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mEglDisplay == EGL_NO_DISPLAY) { 318bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ALOGE("bindTextureImage: invalid display"); 319bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 320bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 321bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 322bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden GLint error; 323bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden while ((error = glGetError()) != GL_NO_ERROR) { 324bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGW("bindTextureImage: clearing GL error: %#04x", error); 325bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 326bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 327bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 328bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT) { 329bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mCurrentTextureBuf == NULL) { 330bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("bindTextureImage: no currently-bound texture"); 331bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return NO_INIT; 3328ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 333bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return bindUnslottedBufferLocked(mEglDisplay); 334bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } else { 335bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLImageKHR image = mEglSlots[mCurrentTexture].mEglImage; 3360eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis 3379fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image); 33874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 3399fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis while ((error = glGetError()) != GL_NO_ERROR) { 340bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("bindTextureImage: error binding external texture image %p" 341bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ": %#04x", image, error); 342bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return UNKNOWN_ERROR; 3438ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 344bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return NO_ERROR; 345bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 346bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 3479a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 348bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFaddenstatus_t SurfaceTexture::checkAndUpdateEglStateLocked() { 349bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLDisplay dpy = eglGetCurrentDisplay(); 350bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLContext ctx = eglGetCurrentContext(); 35186edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis 352bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if ((mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) || 353bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden dpy == EGL_NO_DISPLAY) { 354bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("checkAndUpdateEglState: invalid current EGLDisplay"); 355bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 356bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 357b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 358bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if ((mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) || 359bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ctx == EGL_NO_CONTEXT) { 360bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("checkAndUpdateEglState: invalid current EGLContext"); 361bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 3628ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 36350c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis 364bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglDisplay = dpy; 365bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglContext = ctx; 366bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return NO_ERROR; 3678ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 3688ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 369ef19414bd8b77a26f5751f3845be79025a8263feJesse Hallvoid SurfaceTexture::setReleaseFence(int fenceFd) { 3703d1d09c0c116c42f7d083f87628b5f8377b1f275Jamie Gennis sp<Fence> fence(new Fence(fenceFd)); 37145cb2ba1d52d81e20702b62610422fb09aaedeaeJamie Gennis if (fenceFd == -1 || mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT) 372ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall return; 373b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis status_t err = addReleaseFence(mCurrentTexture, fence); 374b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis if (err != OK) { 375b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis ST_LOGE("setReleaseFence: failed to add the fence: %s (%d)", 376b27254154642575dfb4bbfa79fbedde7d7ee23ddJamie Gennis strerror(-err), err); 377ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 378ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall} 379ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall 38074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatus_t SurfaceTexture::detachFromContext() { 38174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ATRACE_CALL(); 38274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("detachFromContext"); 38374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis Mutex::Autolock lock(mMutex); 38474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 38574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAbandoned) { 38674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: abandoned SurfaceTexture"); 38774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return NO_INIT; 38874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 38974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 39074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (!mAttached) { 39174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: SurfaceTexture is not attached to a " 39274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "context"); 39374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 39474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 39574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 39674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 39774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 39874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 39974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) { 40074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: invalid current EGLDisplay"); 40174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 40274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 40374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 40474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) { 40574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: invalid current EGLContext"); 40674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 40774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 40874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 40974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (dpy != EGL_NO_DISPLAY && ctx != EGL_NO_CONTEXT) { 41074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis status_t err = syncForReleaseLocked(dpy); 41174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (err != OK) { 41274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return err; 41374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 41474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 41574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glDeleteTextures(1, &mTexName); 41674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 41774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 4189aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis // Because we're giving up the EGLDisplay we need to free all the EGLImages 4199aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis // that are associated with it. They'll be recreated when the 4209aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis // SurfaceTexture gets attached to a new OpenGL ES context (and thus gets a 4219aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis // new EGLDisplay). 4229aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis for (int i =0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 4239fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis EGLImageKHR img = mEglSlots[i].mEglImage; 4245c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis if (img != EGL_NO_IMAGE_KHR) { 4259aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis eglDestroyImageKHR(mEglDisplay, img); 4269fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[i].mEglImage = EGL_NO_IMAGE_KHR; 4279aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis } 4289aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis } 4299aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis 43074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglDisplay = EGL_NO_DISPLAY; 43174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglContext = EGL_NO_CONTEXT; 43274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached = false; 43374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 43474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 43574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 43674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 43774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatus_t SurfaceTexture::attachToContext(GLuint tex) { 43874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ATRACE_CALL(); 43974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("attachToContext"); 44074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis Mutex::Autolock lock(mMutex); 44174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 44274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAbandoned) { 44374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: abandoned SurfaceTexture"); 44474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return NO_INIT; 44574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 44674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 44774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAttached) { 44874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: SurfaceTexture is already attached to a " 44974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "context"); 45074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 45174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 45274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 45374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 45474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 45574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 45674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (dpy == EGL_NO_DISPLAY) { 45774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: invalid current EGLDisplay"); 45874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 45974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 46074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 46174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (ctx == EGL_NO_CONTEXT) { 46274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: invalid current EGLContext"); 46374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 46474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 46574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 46674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // We need to bind the texture regardless of whether there's a current 46774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // buffer. 46874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glBindTexture(mTexTarget, tex); 46974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 47074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mCurrentTextureBuf != NULL) { 4715c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis // The EGLImageKHR that was associated with the slot was destroyed when 4725c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis // the SurfaceTexture was detached from the old context, so we need to 4735c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis // recreate it here. 474bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = bindUnslottedBufferLocked(dpy); 475bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 47674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return err; 47774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 47874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 47974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 48074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglDisplay = dpy; 48174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglContext = ctx; 48274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mTexName = tex; 48374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached = true; 48474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 48574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 48674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 48774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 488bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFaddenstatus_t SurfaceTexture::bindUnslottedBufferLocked(EGLDisplay dpy) { 489bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGV("bindUnslottedBuffer ct=%d ctb=%p", 490bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTexture, mCurrentTextureBuf.get()); 491bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 492bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Create a temporary EGLImageKHR. 493bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLImageKHR image = createImage(dpy, mCurrentTextureBuf); 494bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (image == EGL_NO_IMAGE_KHR) { 495bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return UNKNOWN_ERROR; 496bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 497bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 498bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Attach the current buffer to the GL texture. 499bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image); 500bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 501bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden GLint error; 502bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = OK; 503bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden while ((error = glGetError()) != GL_NO_ERROR) { 504bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("bindUnslottedBuffer: error binding external texture image %p " 505bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden "(slot %d): %#04x", image, mCurrentTexture, error); 506bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = UNKNOWN_ERROR; 507bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 508bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 509bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We destroy the EGLImageKHR here because the current buffer may no 510bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // longer be associated with one of the buffer slots, so we have 511bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // nowhere to to store it. If the buffer is still associated with a 512bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // slot then another EGLImageKHR will be created next time that buffer 513bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // gets acquired in updateTexImage. 514bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden eglDestroyImageKHR(dpy, image); 515bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 516bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 517bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 518bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 519bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 52074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennisstatus_t SurfaceTexture::syncForReleaseLocked(EGLDisplay dpy) { 52174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("syncForReleaseLocked"); 52274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 52301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 52401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (useNativeFenceSync) { 52501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLSyncKHR sync = eglCreateSyncKHR(dpy, 52601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); 52701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (sync == EGL_NO_SYNC_KHR) { 52801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error creating EGL fence: %#x", 52901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglGetError()); 53074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return UNKNOWN_ERROR; 53174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 53201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis glFlush(); 53301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis int fenceFd = eglDupNativeFenceFDANDROID(dpy, sync); 53498ff0597bd9e57ba133d54f8f09841f96955cba1Jamie Gennis eglDestroySyncKHR(dpy, sync); 53501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fenceFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { 53601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error dup'ing native fence " 53701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fd: %#x", eglGetError()); 53801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 53901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 54001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis sp<Fence> fence(new Fence(fenceFd)); 5419504eb915c9628e130f45019bdefda0168089886Jesse Hall status_t err = addReleaseFenceLocked(mCurrentTexture, fence); 54201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (err != OK) { 54301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error adding release fence: " 54401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "%s (%d)", strerror(-err), err); 54501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return err; 54601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 54701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } else if (mUseFenceSync) { 54801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLSyncKHR fence = mEglSlots[mCurrentTexture].mEglFence; 54901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fence != EGL_NO_SYNC_KHR) { 55001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // There is already a fence for the current slot. We need to 55101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // wait on that before replacing it with another fence to 55201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // ensure that all outstanding buffer accesses have completed 55301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // before the producer accesses it. 55401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000); 55501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (result == EGL_FALSE) { 55601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error waiting for previous " 55701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fence: %#x", eglGetError()); 55801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 55901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 56001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: timeout waiting for previous " 56101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fence"); 56201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return TIMED_OUT; 56301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 56401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglDestroySyncKHR(dpy, fence); 56501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 56674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 56701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // Create a fence for the outstanding accesses in the current 56801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // OpenGL ES context. 56901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL); 57001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fence == EGL_NO_SYNC_KHR) { 57101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error creating fence: %#x", 57201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglGetError()); 57301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 57401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 57501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis glFlush(); 57601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis mEglSlots[mCurrentTexture].mEglFence = fence; 57774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 57874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 57974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 58074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 58174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 58274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 5837a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopianbool SurfaceTexture::isExternalFormat(uint32_t format) 5847a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian{ 5857a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian switch (format) { 5867a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // supported YUV formats 5877a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YV12: 5887a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Legacy/deprecated YUV formats 5897a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_SP: 5907a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCrCb_420_SP: 5917a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_I: 5927a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 5937a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian } 5947a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 5957a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Any OEM format needs to be considered 5967a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian if (format>=0x100 && format<=0x1FF) 5977a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 5987a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 5997a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return false; 6007a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 6017a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 6027a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias AgopianGLenum SurfaceTexture::getCurrentTextureTarget() const { 603fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis return mTexTarget; 6047a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 6057a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 606f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisvoid SurfaceTexture::getTransformMatrix(float mtx[16]) { 607f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis Mutex::Autolock lock(mMutex); 608736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix)); 609736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis} 610736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis 6115c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennisvoid SurfaceTexture::setFilteringEnabled(bool enabled) { 6125c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis Mutex::Autolock lock(mMutex); 613e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (mAbandoned) { 614e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian ST_LOGE("setFilteringEnabled: SurfaceTexture is abandoned!"); 615e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian return; 616e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian } 6175c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bool needsRecompute = mFilteringEnabled != enabled; 6185c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis mFilteringEnabled = enabled; 619e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 620e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (needsRecompute && mCurrentTextureBuf==NULL) { 621e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian ST_LOGD("setFilteringEnabled called with mCurrentTextureBuf == NULL"); 622e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian } 623e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 624e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (needsRecompute && mCurrentTextureBuf != NULL) { 625e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian computeCurrentTransformMatrixLocked(); 6265c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 6275c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis} 6285c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis 629e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopianvoid SurfaceTexture::computeCurrentTransformMatrixLocked() { 630e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian ST_LOGV("computeCurrentTransformMatrixLocked"); 631f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 632a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float xform[16]; 633a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 634a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = mtxIdentity[i]; 635a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 636a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) { 637a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 638a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipH); 639a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 640a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 641a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 642a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 643a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) { 644a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 645a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipV); 646a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 647a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 648a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 649a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 650a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 651a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 652a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxRot90); 653a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 654a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 655a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 656f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis } 657f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 658eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam sp<GraphicBuffer>& buf(mCurrentTextureBuf); 659e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 660e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (buf == NULL) { 661e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian ST_LOGD("computeCurrentTransformMatrixLocked: mCurrentTextureBuf is NULL"); 662e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian } 663e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 664d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis Rect cropRect = mCurrentCrop; 6655c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis float tx = 0.0f, ty = 0.0f, sx = 1.0f, sy = 1.0f; 6665c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis float bufferWidth = buf->getWidth(); 6675c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis float bufferHeight = buf->getHeight(); 668d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis if (!cropRect.isEmpty()) { 6695c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis float shrinkAmount = 0.0f; 6705c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis if (mFilteringEnabled) { 6715c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // In order to prevent bilinear sampling beyond the edge of the 6725c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // crop rectangle we may need to shrink it by 2 texels in each 6735c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // dimension. Normally this would just need to take 1/2 a texel 6745c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // off each end, but because the chroma channels of YUV420 images 6755c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // are subsampled we may need to shrink the crop region by a whole 6765c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // texel on each side. 6775c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis switch (buf->getPixelFormat()) { 6785c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGBA_8888: 6795c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGBX_8888: 6805c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGB_888: 6815c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGB_565: 6825c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_BGRA_8888: 6835c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGBA_5551: 6845c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGBA_4444: 6855c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // We know there's no subsampling of any channels, so we 6865c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // only need to shrink by a half a pixel. 6875c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis shrinkAmount = 0.5; 6884f9c284de4b9159126f69eb1219c410f66cc872cRomain Guy break; 6899fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 6905c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis default: 6915c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // If we don't recognize the format, we must assume the 6925c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // worst case (that we care about), which is YUV420. 6935c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis shrinkAmount = 1.0; 6949fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis break; 6955c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 6965c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 6975c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis 6985c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // Only shrink the dimensions that are not the size of the buffer. 6995c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis if (cropRect.width() < bufferWidth) { 7005c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis tx = (float(cropRect.left) + shrinkAmount) / bufferWidth; 7015c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis sx = (float(cropRect.width()) - (2.0f * shrinkAmount)) / 7025c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bufferWidth; 7035c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 7045c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis if (cropRect.height() < bufferHeight) { 7055c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis ty = (float(bufferHeight - cropRect.bottom) + shrinkAmount) / 7065c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bufferHeight; 7075c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis sy = (float(cropRect.height()) - (2.0f * shrinkAmount)) / 7085c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bufferHeight; 7095c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 710a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 711f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis float crop[16] = { 712a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis sx, 0, 0, 0, 713a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis 0, sy, 0, 0, 714f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 715d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis tx, ty, 0, 1, 716f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis }; 717f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 718a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float mtxBeforeFlipV[16]; 719a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(mtxBeforeFlipV, crop, xform); 720a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis 721a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // SurfaceFlinger expects the top of its window textures to be at a Y 722a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // coordinate of 0, so SurfaceTexture must behave the same way. We don't 723a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // want to expose this to applications, however, so we must add an 724a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // additional vertical flip to the transform after all the other transforms. 725736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis mtxMul(mCurrentTransformMatrix, mtxFlipV, mtxBeforeFlipV); 726f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 727f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 7281d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvalansecs_t SurfaceTexture::getTimestamp() { 7296ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("getTimestamp"); 7301d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala Mutex::Autolock lock(mMutex); 7311d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala return mCurrentTimestamp; 7321d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala} 7331d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala 7348ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie GennisEGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy, 7358ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis const sp<GraphicBuffer>& graphicBuffer) { 7368ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLClientBuffer cbuf = (EGLClientBuffer)graphicBuffer->getNativeBuffer(); 7378ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLint attrs[] = { 7388ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 7398ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_NONE, 7408ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis }; 7418ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, 7428ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs); 7433cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian if (image == EGL_NO_IMAGE_KHR) { 7443cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian EGLint error = eglGetError(); 745fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("error creating EGLImage: %#x", error); 7468ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 7478ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return image; 7488ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 7498ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 7507a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopiansp<GraphicBuffer> SurfaceTexture::getCurrentBuffer() const { 7517a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 7527a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTextureBuf; 7537a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 7547a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7557a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias AgopianRect SurfaceTexture::getCurrentCrop() const { 7567a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 757016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 758016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam Rect outCrop = mCurrentCrop; 759016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { 760016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t newWidth = mCurrentCrop.width(); 761016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t newHeight = mCurrentCrop.height(); 762016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 763016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (newWidth * mDefaultHeight > newHeight * mDefaultWidth) { 764016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam newWidth = newHeight * mDefaultWidth / mDefaultHeight; 765016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ST_LOGV("too wide: newWidth = %d", newWidth); 766016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } else if (newWidth * mDefaultHeight < newHeight * mDefaultWidth) { 767016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam newHeight = newWidth * mDefaultHeight / mDefaultWidth; 768016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ST_LOGV("too tall: newHeight = %d", newHeight); 769016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 770016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 771016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The crop is too wide 772016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (newWidth < mCurrentCrop.width()) { 773016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t dw = (newWidth - mCurrentCrop.width())/2; 774016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.left -=dw; 775016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.right += dw; 776016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The crop is too tall 777016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } else if (newHeight < mCurrentCrop.height()) { 778016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t dh = (newHeight - mCurrentCrop.height())/2; 779016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.top -= dh; 780016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.bottom += dh; 781016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 782016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 783016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ST_LOGV("getCurrentCrop final crop [%d,%d,%d,%d]", 784016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.left, outCrop.top, 785016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.right,outCrop.bottom); 786016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 787016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 788016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam return outCrop; 7897a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 7907a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7917a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopianuint32_t SurfaceTexture::getCurrentTransform() const { 7927a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 7937a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTransform; 7947a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 7957a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7967734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopianuint32_t SurfaceTexture::getCurrentScalingMode() const { 7977734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian Mutex::Autolock lock(mMutex); 7987734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian return mCurrentScalingMode; 7997734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian} 8007734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian 801dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hallsp<Fence> SurfaceTexture::getCurrentFence() const { 802dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall Mutex::Autolock lock(mMutex); 803dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall return mCurrentFence; 804dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall} 805dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 80661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennisstatus_t SurfaceTexture::doGLFenceWait() const { 80761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis Mutex::Autolock lock(mMutex); 8083941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis return doGLFenceWaitLocked(); 8093941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis} 8103941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis 8113941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennisstatus_t SurfaceTexture::doGLFenceWaitLocked() const { 81261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 81361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 81461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 81561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 81661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (mEglDisplay != dpy || mEglDisplay == EGL_NO_DISPLAY) { 81761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: invalid current EGLDisplay"); 81861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return INVALID_OPERATION; 81961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 82061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 82161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (mEglContext != ctx || mEglContext == EGL_NO_CONTEXT) { 82261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: invalid current EGLContext"); 82361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return INVALID_OPERATION; 82461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 82561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 82661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (mCurrentFence != NULL) { 82761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (useWaitSync) { 82861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // Create an EGLSyncKHR from the current fence. 82961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis int fenceFd = mCurrentFence->dup(); 83061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (fenceFd == -1) { 83161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: error dup'ing fence fd: %d", errno); 83261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return -errno; 83361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 83461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLint attribs[] = { 83561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd, 83661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_NONE 83761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis }; 83861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLSyncKHR sync = eglCreateSyncKHR(dpy, 83961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_SYNC_NATIVE_FENCE_ANDROID, attribs); 84061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (sync == EGL_NO_SYNC_KHR) { 84161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis close(fenceFd); 84261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: error creating EGL fence: %#x", 84361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglGetError()); 84461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return UNKNOWN_ERROR; 84561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 84661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 84761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // XXX: The spec draft is inconsistent as to whether this should 84861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // return an EGLint or void. Ignore the return value for now, as 84961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // it's not strictly needed. 85061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglWaitSyncANDROID(dpy, sync, 0); 85161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLint eglErr = eglGetError(); 85261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglDestroySyncKHR(dpy, sync); 85361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (eglErr != EGL_SUCCESS) { 85461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: error waiting for EGL fence: %#x", 85561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglErr); 85661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return UNKNOWN_ERROR; 85761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 85861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } else { 859ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall status_t err = mCurrentFence->waitForever(1000, 860ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall "SurfaceTexture::doGLFenceWaitLocked"); 86161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (err != NO_ERROR) { 86261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: error waiting for fence: %d", err); 86361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return err; 86461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 86561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 86661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 86761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 86861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return NO_ERROR; 86961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis} 87061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 87159769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennisbool SurfaceTexture::isSynchronousMode() const { 87259769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis Mutex::Autolock lock(mMutex); 873b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->isSynchronousMode(); 87459769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis} 87559769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis 876fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennisvoid SurfaceTexture::freeBufferLocked(int slotIndex) { 877fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("freeBufferLocked: slotIndex=%d", slotIndex); 8789abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (slotIndex == mCurrentTexture) { 8799abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; 8809abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 8819fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis EGLImageKHR img = mEglSlots[slotIndex].mEglImage; 8829aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis if (img != EGL_NO_IMAGE_KHR) { 8839aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis ST_LOGV("destroying EGLImage dpy=%p img=%p", mEglDisplay, img); 8849aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis eglDestroyImageKHR(mEglDisplay, img); 885fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 8869fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[slotIndex].mEglImage = EGL_NO_IMAGE_KHR; 8879fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase::freeBufferLocked(slotIndex); 888fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 889fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 8909fea3421ffddf6480f57f55a25936a886043d909Jamie Gennisvoid SurfaceTexture::abandonLocked() { 8919fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ST_LOGV("abandonLocked"); 8929fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentTextureBuf.clear(); 8939fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase::abandonLocked(); 8947b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis} 8957b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 896fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennisvoid SurfaceTexture::setName(const String8& name) { 897eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 898fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis mName = name; 899b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferQueue->setConsumerName(name); 900b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 901b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 902b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setDefaultBufferFormat(uint32_t defaultFormat) { 903b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 904b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setDefaultBufferFormat(defaultFormat); 905b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 906b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 907b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setConsumerUsageBits(uint32_t usage) { 908b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 90985b217668d6840c8e6a109adfb99461313676f8dEino-Ville Talvala usage |= DEFAULT_USAGE_FLAGS; 910b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setConsumerUsageBits(usage); 911b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 912b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 913b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setTransformHint(uint32_t hint) { 914b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 915b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setTransformHint(hint); 916b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 917b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 918b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam// Used for refactoring BufferQueue from SurfaceTexture 919b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam// Should not be in final interface once users of SurfaceTexture are clean up. 920b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setSynchronousMode(bool enabled) { 921b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 922b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setSynchronousMode(enabled); 923b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 924b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 9259fea3421ffddf6480f57f55a25936a886043d909Jamie Gennisvoid SurfaceTexture::dumpLocked(String8& result, const char* prefix, 9269fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis char* buffer, size_t size) const 92768c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian{ 9289fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis snprintf(buffer, size, 9299fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis "%smTexName=%d mCurrentTexture=%d\n" 9309fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis "%smCurrentCrop=[%d,%d,%d,%d] mCurrentTransform=%#x\n", 9319fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis prefix, mTexName, mCurrentTexture, prefix, mCurrentCrop.left, 9329fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom, 9339fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentTransform); 93468c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian result.append(buffer); 93568c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 9369fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase::dumpLocked(result, prefix, buffer, size); 93768c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian} 93868c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 939f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]) { 940f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3]; 941f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3]; 942f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3]; 943f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3]; 944f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 945f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7]; 946f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7]; 947f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7]; 948f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7]; 949f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 950f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11]; 951f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11]; 952f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11]; 953f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11]; 954f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 955f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15]; 956f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15]; 957f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15]; 958f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15]; 959f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 960f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 9618ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis}; // namespace android 962