GLConsumer.cpp revision b267579ba8dfe3f47d2a481c5a3c2254e3d565a1
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), 118eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mAbandoned(false), 119eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT) 1206b091c53000c843211c218ce40287a7edca9bc63Daniel Lam{ 121eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // Choose a name using the PID and a process-unique ID. 122eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId()); 1236ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("SurfaceTexture"); 124b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam if (bufferQueue == 0) { 125b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 126b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam ST_LOGV("Creating a new BufferQueue"); 127b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferQueue = new BufferQueue(allowSynchronousMode); 128b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam } 129b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam else { 130b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferQueue = bufferQueue; 131b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam } 132b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferQueue->setConsumerName(mName); 133b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 134fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis memcpy(mCurrentTransformMatrix, mtxIdentity, 135fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis sizeof(mCurrentTransformMatrix)); 1368ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 1378ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 1388ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie GennisSurfaceTexture::~SurfaceTexture() { 1396ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("~SurfaceTexture"); 140b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 141eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam abandon(); 1428ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 1438ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 1448072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopianstatus_t SurfaceTexture::setBufferCountServer(int bufferCount) { 1458072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian Mutex::Autolock lock(mMutex); 146b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setBufferCountServer(bufferCount); 1478072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian} 1488072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 1498ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 150a5c75c01620179ce00812354778a29a80d76e71fMathias Agopianstatus_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h) 151a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian{ 152b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 153b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setDefaultBufferSize(w, h); 154a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian} 155a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian 1568ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennisstatus_t SurfaceTexture::updateTexImage() { 1571c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis ATRACE_CALL(); 1586ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("updateTexImage"); 1598ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis Mutex::Autolock lock(mMutex); 1608ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 161e47498f8f258967ff62d070f08ff2dadd4ae2b56Mathias Agopian if (mAbandoned) { 162fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("calling updateTexImage() on an abandoned SurfaceTexture"); 1638e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian return NO_INIT; 164e47498f8f258967ff62d070f08ff2dadd4ae2b56Mathias Agopian } 165e47498f8f258967ff62d070f08ff2dadd4ae2b56Mathias Agopian 166b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam BufferQueue::BufferItem item; 167eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 16850c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis // In asynchronous mode the list is guaranteed to be one buffer 16950c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis // deep, while in synchronous mode we use the oldest buffer. 170b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam if (mBufferQueue->acquire(&item) == NO_ERROR) { 171eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam int buf = item.mBuf; 172eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // This buffer was newly allocated, so we need to clean up on our side 173eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (item.mGraphicBuffer != NULL) { 174eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[buf].mGraphicBuffer = 0; 175eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (mEGLSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) { 176eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam eglDestroyImageKHR(mEGLSlots[buf].mEglDisplay, 177eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[buf].mEglImage); 178eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[buf].mEglImage = EGL_NO_IMAGE_KHR; 179eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[buf].mEglDisplay = EGL_NO_DISPLAY; 180eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 181eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[buf].mGraphicBuffer = item.mGraphicBuffer; 182eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 183b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 184f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis // Update the GL texture object. 185eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam EGLImageKHR image = mEGLSlots[buf].mEglImage; 18686edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 1878ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis if (image == EGL_NO_IMAGE_KHR) { 188eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (item.mGraphicBuffer == 0) { 189fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("buffer at slot %d is null", buf); 1908e19c2e97e11505ee2ecf336275fd956f2ccfa22Mathias Agopian return BAD_VALUE; 191e47498f8f258967ff62d070f08ff2dadd4ae2b56Mathias Agopian } 192eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam image = createImage(dpy, item.mGraphicBuffer); 193eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[buf].mEglImage = image; 194eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[buf].mEglDisplay = dpy; 1953cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian if (image == EGL_NO_IMAGE_KHR) { 1963cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian // NOTE: if dpy was invalid, createImage() is guaranteed to 1973cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian // fail. so we'd end up here. 1983cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian return -EINVAL; 1993cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian } 2008ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 2010eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis 2020eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis GLint error; 2030eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis while ((error = glGetError()) != GL_NO_ERROR) { 204fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGW("updateTexImage: clearing GL error: %#04x", error); 2050eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis } 2067a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 207fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis glBindTexture(mTexTarget, mTexName); 208fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image); 2097a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 2100eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis bool failed = false; 2110eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis while ((error = glGetError()) != GL_NO_ERROR) { 212fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("error binding external texture image %p (slot %d): %#04x", 213b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian image, buf, error); 2140eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis failed = true; 2150eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis } 2160eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis if (failed) { 217b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferQueue->releaseBuffer(buf, mEGLSlots[buf].mEglDisplay, 218eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[buf].mFence); 2198ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return -EINVAL; 2208ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 2219a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 222b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 22386edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis if (mUseFenceSync) { 22486edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis EGLSyncKHR fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, 22586edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis NULL); 22686edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis if (fence == EGL_NO_SYNC_KHR) { 227e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("updateTexImage: error creating fence: %#x", 22886edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis eglGetError()); 229b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferQueue->releaseBuffer(buf, mEGLSlots[buf].mEglDisplay, 230eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[buf].mFence); 23186edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis return -EINVAL; 23286edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis } 23386edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis glFlush(); 234eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[mCurrentTexture].mFence = fence; 23586edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis } 23686edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis } 23786edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis 23886edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis ST_LOGV("updateTexImage: (slot=%d buf=%p) -> (slot=%d buf=%p)", 23986edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis mCurrentTexture, 24086edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis mCurrentTextureBuf != NULL ? mCurrentTextureBuf->handle : 0, 241eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam buf, item.mGraphicBuffer != NULL ? item.mGraphicBuffer->handle : 0); 2426ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis 243eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // release old buffer 244b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferQueue->releaseBuffer(mCurrentTexture, 245eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[mCurrentTexture].mEglDisplay, 246eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[mCurrentTexture].mFence); 247b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 2489a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis // Update the SurfaceTexture state. 249b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mCurrentTexture = buf; 250eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mCurrentTextureBuf = mEGLSlots[buf].mGraphicBuffer; 251eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mCurrentCrop = item.mCrop; 252eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mCurrentTransform = item.mTransform; 253eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mCurrentScalingMode = item.mScalingMode; 254eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mCurrentTimestamp = item.mTimestamp; 255736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis computeCurrentTransformMatrix(); 25650c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis 25750c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis // Now that we've passed the point at which failures can happen, 25850c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis // it's safe to remove the buffer from the front of the queue. 259eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 2607a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian } else { 2617a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // We always bind the texture even if we don't update its contents. 262fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis glBindTexture(mTexTarget, mTexName); 2638ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 26450c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis 2658ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return OK; 2668ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 2678ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 2687a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopianbool SurfaceTexture::isExternalFormat(uint32_t format) 2697a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian{ 2707a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian switch (format) { 2717a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // supported YUV formats 2727a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YV12: 2737a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Legacy/deprecated YUV formats 2747a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_SP: 2757a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCrCb_420_SP: 2767a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_I: 2777a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 2787a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian } 2797a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 2807a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Any OEM format needs to be considered 2817a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian if (format>=0x100 && format<=0x1FF) 2827a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 2837a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 2847a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return false; 2857a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 2867a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 2877a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias AgopianGLenum SurfaceTexture::getCurrentTextureTarget() const { 288fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis return mTexTarget; 2897a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 2907a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 291f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisvoid SurfaceTexture::getTransformMatrix(float mtx[16]) { 292f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis Mutex::Autolock lock(mMutex); 293736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix)); 294736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis} 295736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis 296736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennisvoid SurfaceTexture::computeCurrentTransformMatrix() { 2976ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("computeCurrentTransformMatrix"); 298f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 299a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float xform[16]; 300a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 301a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = mtxIdentity[i]; 302a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 303a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) { 304a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 305a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipH); 306a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 307a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 308a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 309a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 310a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) { 311a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 312a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipV); 313a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 314a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 315a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 316a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 317a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 318a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 319a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxRot90); 320a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 321a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 322a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 323f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis } 324f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 325eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam sp<GraphicBuffer>& buf(mCurrentTextureBuf); 326a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float tx, ty, sx, sy; 327a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (!mCurrentCrop.isEmpty()) { 328d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // In order to prevent bilinear sampling at the of the crop rectangle we 329d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // may need to shrink it by 2 texels in each direction. Normally this 330d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // would just need to take 1/2 a texel off each end, but because the 331d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // chroma channels will likely be subsampled we need to chop off a whole 332d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // texel. This will cause artifacts if someone does nearest sampling 333d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // with 1:1 pixel:texel ratio, but it's impossible to simultaneously 334d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // accomodate the bilinear and nearest sampling uses. 335d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // 336d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // If nearest sampling turns out to be a desirable usage of these 337d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // textures then we could add the ability to switch a SurfaceTexture to 338d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // nearest-mode. Preferably, however, the image producers (video 339d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // decoder, camera, etc.) would simply not use a crop rectangle (or at 340d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // least not tell the framework about it) so that the GPU can do the 341d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis // correct edge behavior. 342d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis int xshrink = 0, yshrink = 0; 343d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis if (mCurrentCrop.left > 0) { 344d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis tx = float(mCurrentCrop.left + 1) / float(buf->getWidth()); 345d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis xshrink++; 346d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } else { 347d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis tx = 0.0f; 348d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 349a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian if (mCurrentCrop.right < int32_t(buf->getWidth())) { 350d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis xshrink++; 351d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 352a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian if (mCurrentCrop.bottom < int32_t(buf->getHeight())) { 353d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis ty = (float(buf->getHeight() - mCurrentCrop.bottom) + 1.0f) / 354d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis float(buf->getHeight()); 355d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis yshrink++; 356d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } else { 357d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis ty = 0.0f; 358d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 359d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis if (mCurrentCrop.top > 0) { 360d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis yshrink++; 361d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis } 362d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis sx = float(mCurrentCrop.width() - xshrink) / float(buf->getWidth()); 363d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis sy = float(mCurrentCrop.height() - yshrink) / float(buf->getHeight()); 364a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } else { 365a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis tx = 0.0f; 366a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis ty = 0.0f; 367a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis sx = 1.0f; 368a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis sy = 1.0f; 369a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 370f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis float crop[16] = { 371a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis sx, 0, 0, 0, 372a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis 0, sy, 0, 0, 373f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 374d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis tx, ty, 0, 1, 375f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis }; 376f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 377a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float mtxBeforeFlipV[16]; 378a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(mtxBeforeFlipV, crop, xform); 379a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis 380a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // SurfaceFlinger expects the top of its window textures to be at a Y 381a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // coordinate of 0, so SurfaceTexture must behave the same way. We don't 382a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // want to expose this to applications, however, so we must add an 383a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // additional vertical flip to the transform after all the other transforms. 384736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis mtxMul(mCurrentTransformMatrix, mtxFlipV, mtxBeforeFlipV); 385f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 386f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 3871d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvalansecs_t SurfaceTexture::getTimestamp() { 3886ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("getTimestamp"); 3891d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala Mutex::Autolock lock(mMutex); 3901d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala return mCurrentTimestamp; 3911d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala} 3921d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala 393c4d4aeab52435c177ded6abdd578fec8191f0f5dJamie Gennisvoid SurfaceTexture::setFrameAvailableListener( 394292a31a4c2ae2f6faf134e8e4a726583017dad06Pannag Sanketi const sp<FrameAvailableListener>& listener) { 3956ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("setFrameAvailableListener"); 396c4d4aeab52435c177ded6abdd578fec8191f0f5dJamie Gennis Mutex::Autolock lock(mMutex); 397b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferQueue->setFrameAvailableListener(listener); 398c4d4aeab52435c177ded6abdd578fec8191f0f5dJamie Gennis} 399c4d4aeab52435c177ded6abdd578fec8191f0f5dJamie Gennis 4008ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie GennisEGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy, 4018ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis const sp<GraphicBuffer>& graphicBuffer) { 4028ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLClientBuffer cbuf = (EGLClientBuffer)graphicBuffer->getNativeBuffer(); 4038ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLint attrs[] = { 4048ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 4058ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_NONE, 4068ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis }; 4078ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, 4088ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs); 4093cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian if (image == EGL_NO_IMAGE_KHR) { 4103cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian EGLint error = eglGetError(); 411fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("error creating EGLImage: %#x", error); 4128ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 4138ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return image; 4148ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 4158ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 4167a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopiansp<GraphicBuffer> SurfaceTexture::getCurrentBuffer() const { 4177a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 4187a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTextureBuf; 4197a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 4207a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 4217a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias AgopianRect SurfaceTexture::getCurrentCrop() const { 4227a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 4237a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentCrop; 4247a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 4257a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 4267a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopianuint32_t SurfaceTexture::getCurrentTransform() const { 4277a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 4287a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTransform; 4297a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 4307a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 4317734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopianuint32_t SurfaceTexture::getCurrentScalingMode() const { 4327734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian Mutex::Autolock lock(mMutex); 4337734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian return mCurrentScalingMode; 4347734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian} 4357734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian 43659769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennisbool SurfaceTexture::isSynchronousMode() const { 43759769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis Mutex::Autolock lock(mMutex); 438b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->isSynchronousMode(); 43959769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis} 44059769469e4b9b2d8b12c020eb44b030b3927a50bJamie Gennis 4417b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennisvoid SurfaceTexture::abandon() { 4427b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis Mutex::Autolock lock(mMutex); 4437b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis mAbandoned = true; 44497a9884edcc6fbb311386ecfcd6e3045437f0df0Mathias Agopian mCurrentTextureBuf.clear(); 445eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 446eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // destroy all egl buffers 447b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam for (int i =0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 448eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[i].mGraphicBuffer = 0; 449eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam if (mEGLSlots[i].mEglImage != EGL_NO_IMAGE_KHR) { 450eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam eglDestroyImageKHR(mEGLSlots[i].mEglDisplay, 451eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[i].mEglImage); 452eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[i].mEglImage = EGL_NO_IMAGE_KHR; 453eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mEGLSlots[i].mEglDisplay = EGL_NO_DISPLAY; 454eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 455eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam } 456eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 457eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam // disconnect from the BufferQueue 458b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferQueue->consumerDisconnect(); 4597b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis} 4607b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 461fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennisvoid SurfaceTexture::setName(const String8& name) { 462eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 463fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis mName = name; 464b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferQueue->setConsumerName(name); 465b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 466b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 467b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setDefaultBufferFormat(uint32_t defaultFormat) { 468b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 469b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setDefaultBufferFormat(defaultFormat); 470b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 471b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 472b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setConsumerUsageBits(uint32_t usage) { 473b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 474b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setConsumerUsageBits(usage); 475b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 476b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 477b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setTransformHint(uint32_t hint) { 478b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 479b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setTransformHint(hint); 480b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 481b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 482b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam// Used for refactoring BufferQueue from SurfaceTexture 483b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam// Should not be in final interface once users of SurfaceTexture are clean up. 484b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setSynchronousMode(bool enabled) { 485b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 486b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setSynchronousMode(enabled); 487b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 488b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 489b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam// Used for refactoring, should not be in final interface 490b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamsp<BufferQueue> SurfaceTexture::getBufferQueue() const { 491b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 492b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue; 493b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 494b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 495b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam// Used for refactoring, should not be in final interface 496b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::setBufferCount(int bufferCount) { 497b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 498b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setBufferCount(bufferCount); 499b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 500b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 501b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam// Used for refactoring, should not be in final interface 502b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lamstatus_t SurfaceTexture::connect(int api, 503b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) { 504b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 505b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->connect(api, outWidth, outHeight, outTransform); 506fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis} 507fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis 50868c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopianvoid SurfaceTexture::dump(String8& result) const 50968c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian{ 51068c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian char buffer[1024]; 51168c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian dump(result, "", buffer, 1024); 51268c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian} 51368c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 51468c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopianvoid SurfaceTexture::dump(String8& result, const char* prefix, 51568c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian char* buffer, size_t SIZE) const 51668c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian{ 51768c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian Mutex::Autolock _l(mMutex); 518eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam snprintf(buffer, SIZE, "%smTexName=%d\n", prefix, mTexName); 51968c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian result.append(buffer); 52068c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 52168c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian snprintf(buffer, SIZE, 522eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam "%snext : {crop=[%d,%d,%d,%d], transform=0x%02x, current=%d}\n" 523eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam ,prefix, mCurrentCrop.left, 52468c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom, 525eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mCurrentTransform, mCurrentTexture 52668c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian ); 52768c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian result.append(buffer); 52868c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 529eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 530b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferQueue->dump(result, prefix, buffer, SIZE); 53168c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian} 53268c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 533f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]) { 534f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3]; 535f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3]; 536f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3]; 537f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3]; 538f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 539f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7]; 540f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7]; 541f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7]; 542f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7]; 543f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 544f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11]; 545f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11]; 546f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11]; 547f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11]; 548f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 549f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15]; 550f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15]; 551f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15]; 552f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15]; 553f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 554f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 5558ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis}; // namespace android 556