GLConsumer.cpp revision 595264f1af12e25dce57d7c5b1d52ed86ac0d0c9
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 172adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden#define LOG_TAG "GLConsumer" 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 31ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <gui/GLConsumer.h> 3290ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/IGraphicBufferAlloc.h> 3390ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/ISurfaceComposer.h> 3490ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/SurfaceComposerClient.h> 3541f673c9b3aac0d96e41c928845c39186d565212Mathias Agopian 3690ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <private/gui/ComposerService.h> 37ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h> 388ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 398ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <utils/Log.h> 4068c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian#include <utils/String8.h> 411c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 428ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 4397eba8904c2f221c42a9473407223a4c3a213f75Andy McFaddennamespace android { 4497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden 452adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden// Macros for including the GLConsumer name in log messages 466807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block#define ST_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__) 479d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block#define ST_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__) 48a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block#define ST_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__) 4932397c1cd3327905173b36baa6fd1c579bc328ffSteve Block#define ST_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__) 50e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block#define ST_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__) 5129b5762efc359022168e5099c1d17925444d3147Mathias Agopian 52f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis// Transform matrices 53f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxIdentity[16] = { 54f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 0, 55f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 56f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 57f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 0, 1, 58f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 59f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxFlipH[16] = { 60f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis -1, 0, 0, 0, 61f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 62f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 63f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 1, 64f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 65f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxFlipV[16] = { 66f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 0, 67f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, -1, 0, 0, 68f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 69f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 1, 70f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 71f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxRot90[16] = { 72f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 73f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis -1, 0, 0, 0, 74f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 75f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 1, 76f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 77f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 78f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]); 79f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 80fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis 818f938a53385a3c6d1c6aa24b3f38437bb2cc47aeMathias AgopianGLConsumer::GLConsumer(const sp<BufferQueue>& bq, GLuint tex, 82595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian GLenum texTarget, bool useFenceSync, bool isControlledByApp) : 83595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian ConsumerBase(bq, isControlledByApp), 841d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTransform(0), 85e692ab9a6be63193c5b52a6562d85d06c40463b8Mathias Agopian mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 861df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis mCurrentFence(Fence::NO_FENCE), 871d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTimestamp(0), 88e692ab9a6be63193c5b52a6562d85d06c40463b8Mathias Agopian mDefaultWidth(1), 89e692ab9a6be63193c5b52a6562d85d06c40463b8Mathias Agopian mDefaultHeight(1), 905c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis mFilteringEnabled(true), 91b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mTexName(tex), 9286edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis mUseFenceSync(useFenceSync), 93eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mTexTarget(texTarget), 94ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglDisplay(EGL_NO_DISPLAY), 95ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglContext(EGL_NO_CONTEXT), 9674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), 9774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached(true) 986b091c53000c843211c218ce40287a7edca9bc63Daniel Lam{ 992adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGV("GLConsumer"); 100b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 101fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis memcpy(mCurrentTransformMatrix, mtxIdentity, 102fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis sizeof(mCurrentTransformMatrix)); 103fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 1049fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mBufferQueue->setConsumerUsageBits(DEFAULT_USAGE_FLAGS); 1058ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 1068ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 1072adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setDefaultMaxBufferCount(int bufferCount) { 1088072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian Mutex::Autolock lock(mMutex); 10931a353da225af5329735451c761b430d82dfda1bJamie Gennis return mBufferQueue->setDefaultMaxBufferCount(bufferCount); 1108072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian} 1118072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 1128ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 1132adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setDefaultBufferSize(uint32_t w, uint32_t h) 114a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian{ 115b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 116016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam mDefaultWidth = w; 117016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam mDefaultHeight = h; 118b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setDefaultBufferSize(w, h); 119a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian} 120a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian 1212adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::updateTexImage() { 122bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ATRACE_CALL(); 123bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGV("updateTexImage"); 124bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden Mutex::Autolock lock(mMutex); 125bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 126bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mAbandoned) { 1272adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("updateTexImage: GLConsumer is abandoned!"); 128bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return NO_INIT; 129bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 130bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 131bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Make sure the EGL state is the same as in previous calls. 132bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = checkAndUpdateEglStateLocked(); 133bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 134bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 135bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 136bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 137bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden BufferQueue::BufferItem item; 138bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 139bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Acquire the next buffer. 140bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // In asynchronous mode the list is guaranteed to be one buffer 141bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // deep, while in synchronous mode we use the oldest buffer. 1421585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden err = acquireBufferLocked(&item, 0); 143bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 144bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 145bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We always bind the texture even if we don't update its contents. 146bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGV("updateTexImage: no buffers were available"); 147bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 148bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = NO_ERROR; 149bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } else { 150bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("updateTexImage: acquire failed: %s (%d)", 151bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden strerror(-err), err); 152bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 153bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 154bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 155bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 156bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Release the previous buffer. 157bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = releaseAndUpdateLocked(item); 158bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 159bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We always bind the texture. 160bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 161bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 162bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 163bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 16497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // Bind the new buffer to the GL texture, and wait until it's ready. 16597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden return bindTextureImageLocked(); 1662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian} 1672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 1681585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFaddenstatus_t GLConsumer::acquireBufferLocked(BufferQueue::BufferItem *item, 1691585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden nsecs_t presentWhen) { 1701585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen); 1719fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (err != NO_ERROR) { 1729fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return err; 1739fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 1749fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 1759fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis int slot = item->mBuf; 1769fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (item->mGraphicBuffer != NULL) { 177bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // This buffer has not been acquired before, so we must assume 178bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // that any EGLImage in mEglSlots is stale. 1799fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (mEglSlots[slot].mEglImage != EGL_NO_IMAGE_KHR) { 180bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (!eglDestroyImageKHR(mEglDisplay, mEglSlots[slot].mEglImage)) { 181bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGW("acquireBufferLocked: eglDestroyImageKHR failed for slot=%d", 182bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden slot); 183bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // keep going 184bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 1859fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[slot].mEglImage = EGL_NO_IMAGE_KHR; 1869fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 1879fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 1889fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 1899fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return NO_ERROR; 1909fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis} 1919fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 192c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnarstatus_t GLConsumer::releaseBufferLocked(int buf, 193c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar sp<GraphicBuffer> graphicBuffer, 194c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar EGLDisplay display, EGLSyncKHR eglFence) { 195c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // release the buffer if it hasn't already been discarded by the 196c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // BufferQueue. This can happen, for example, when the producer of this 197c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // buffer has reallocated the original buffer slot after this buffer 198c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // was acquired. 199c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = ConsumerBase::releaseBufferLocked( 200c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar buf, graphicBuffer, display, eglFence); 201d1b330de416adff0d178a5cb7271419d9ed7a89aJamie Gennis mEglSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 2029fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return err; 2039fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis} 2049fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 2052adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::releaseAndUpdateLocked(const BufferQueue::BufferItem& item) 206bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden{ 2079abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam status_t err = NO_ERROR; 2089abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 20974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (!mAttached) { 2102adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("releaseAndUpdate: GLConsumer is not attached to an OpenGL " 21174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "ES context"); 21274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 21374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 21474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 215bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Confirm state. 216bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = checkAndUpdateEglStateLocked(); 217bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 218bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 219ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 220ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 221bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden int buf = item.mBuf; 222bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 223bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // If the mEglSlot entry is empty, create an EGLImage for the gralloc 224bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // buffer currently in the slot in ConsumerBase. 225bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // 226bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We may have to do this even when item.mGraphicBuffer == NULL (which 227bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // means the buffer was previously acquired), if we destroyed the 228bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // EGLImage when detaching from a context but the buffer has not been 229bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // re-allocated. 230bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mEglSlots[buf].mEglImage == EGL_NO_IMAGE_KHR) { 231bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLImageKHR image = createImage(mEglDisplay, mSlots[buf].mGraphicBuffer); 232bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (image == EGL_NO_IMAGE_KHR) { 233bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGW("releaseAndUpdate: unable to createImage on display=%p slot=%d", 234bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglDisplay, buf); 235bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return UNKNOWN_ERROR; 236bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 237bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglSlots[buf].mEglImage = image; 238ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 239ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 240bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Do whatever sync ops we need to do before releasing the old slot. 241bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = syncForReleaseLocked(mEglDisplay); 242bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 243bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Release the buffer we just acquired. It's not safe to 244bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // release the old buffer, so instead we just drop the new frame. 245c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // As we are still under lock since acquireBuffer, it is safe to 246c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // release by slot. 247c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, 248c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mEglDisplay, EGL_NO_SYNC_KHR); 249bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 250bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 251ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 252bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGV("releaseAndUpdate: (slot=%d buf=%p) -> (slot=%d buf=%p)", 253bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTexture, 254bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTextureBuf != NULL ? mCurrentTextureBuf->handle : 0, 255bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden buf, mSlots[buf].mGraphicBuffer->handle); 256eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 257bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // release old buffer 258bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 259c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t status = releaseBufferLocked( 260c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mCurrentTexture, mCurrentTextureBuf, mEglDisplay, 261bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglSlots[mCurrentTexture].mEglFence); 262bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (status != NO_ERROR && status != BufferQueue::STALE_BUFFER_SLOT) { 263bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("releaseAndUpdate: failed to release buffer: %s (%d)", 264bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden strerror(-status), status); 265bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = status; 266bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // keep going, with error raised [?] 2672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 268bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 2692c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 2702adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden // Update the GLConsumer state. 271bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTexture = buf; 272bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTextureBuf = mSlots[buf].mGraphicBuffer; 273bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentCrop = item.mCrop; 274bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTransform = item.mTransform; 275bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentScalingMode = item.mScalingMode; 276bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTimestamp = item.mTimestamp; 277bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentFence = item.mFence; 278bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 279bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden computeCurrentTransformMatrixLocked(); 280bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 281bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 282bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 283bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 2842adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::bindTextureImageLocked() { 285bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mEglDisplay == EGL_NO_DISPLAY) { 286bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ALOGE("bindTextureImage: invalid display"); 287bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 288bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 289bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 290bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden GLint error; 291bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden while ((error = glGetError()) != GL_NO_ERROR) { 292bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGW("bindTextureImage: clearing GL error: %#04x", error); 293bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 294bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 295bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 296bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT) { 297bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mCurrentTextureBuf == NULL) { 298bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("bindTextureImage: no currently-bound texture"); 299bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return NO_INIT; 3008ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 30197eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden status_t err = bindUnslottedBufferLocked(mEglDisplay); 30297eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden if (err != NO_ERROR) { 30397eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden return err; 30497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden } 305bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } else { 306bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLImageKHR image = mEglSlots[mCurrentTexture].mEglImage; 3070eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis 3089fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image); 30974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 3109fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis while ((error = glGetError()) != GL_NO_ERROR) { 311bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("bindTextureImage: error binding external texture image %p" 312bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ": %#04x", image, error); 313bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return UNKNOWN_ERROR; 3148ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 315bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 31697eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden 31797eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // Wait for the new buffer to be ready. 31897eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden return doGLFenceWaitLocked(); 31997eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden 320bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 3219a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 3222adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::checkAndUpdateEglStateLocked() { 323bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLDisplay dpy = eglGetCurrentDisplay(); 324bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLContext ctx = eglGetCurrentContext(); 32586edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis 326bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if ((mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) || 327bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden dpy == EGL_NO_DISPLAY) { 328bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("checkAndUpdateEglState: invalid current EGLDisplay"); 329bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 330bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 331b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 332bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if ((mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) || 333bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ctx == EGL_NO_CONTEXT) { 334bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("checkAndUpdateEglState: invalid current EGLContext"); 335bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 3368ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 33750c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis 338bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglDisplay = dpy; 339bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglContext = ctx; 340bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return NO_ERROR; 3418ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 3428ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 34313f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hallvoid GLConsumer::setReleaseFence(const sp<Fence>& fence) { 34413f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall if (fence->isValid() && 34513f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 346c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = addReleaseFence(mCurrentTexture, 347c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mCurrentTextureBuf, fence); 34813f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall if (err != OK) { 34913f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall ST_LOGE("setReleaseFence: failed to add the fence: %s (%d)", 35013f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall strerror(-err), err); 35113f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall } 352ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 353ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall} 354ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall 3552adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::detachFromContext() { 35674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ATRACE_CALL(); 35774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("detachFromContext"); 35874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis Mutex::Autolock lock(mMutex); 35974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 36074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAbandoned) { 3612adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("detachFromContext: abandoned GLConsumer"); 36274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return NO_INIT; 36374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 36474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 36574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (!mAttached) { 3662adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("detachFromContext: GLConsumer is not attached to a " 36774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "context"); 36874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 36974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 37074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 37174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 37274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 37374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 37474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) { 37574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: invalid current EGLDisplay"); 37674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 37774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 37874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 37974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) { 38074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: invalid current EGLContext"); 38174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 38274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 38374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 38474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (dpy != EGL_NO_DISPLAY && ctx != EGL_NO_CONTEXT) { 38574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis status_t err = syncForReleaseLocked(dpy); 38674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (err != OK) { 38774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return err; 38874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 38974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 39074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glDeleteTextures(1, &mTexName); 39174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 39274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 3939aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis // Because we're giving up the EGLDisplay we need to free all the EGLImages 3949aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis // that are associated with it. They'll be recreated when the 3952adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden // GLConsumer gets attached to a new OpenGL ES context (and thus gets a 3969aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis // new EGLDisplay). 3979aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis for (int i =0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 3989fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis EGLImageKHR img = mEglSlots[i].mEglImage; 3995c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis if (img != EGL_NO_IMAGE_KHR) { 4009aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis eglDestroyImageKHR(mEglDisplay, img); 4019fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[i].mEglImage = EGL_NO_IMAGE_KHR; 4029aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis } 4039aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis } 4049aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis 40574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglDisplay = EGL_NO_DISPLAY; 40674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglContext = EGL_NO_CONTEXT; 40774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached = false; 40874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 40974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 41074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 41174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 4122adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::attachToContext(GLuint tex) { 41374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ATRACE_CALL(); 41474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("attachToContext"); 41574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis Mutex::Autolock lock(mMutex); 41674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 41774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAbandoned) { 4182adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("attachToContext: abandoned GLConsumer"); 41974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return NO_INIT; 42074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 42174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 42274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAttached) { 4232adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("attachToContext: GLConsumer is already attached to a " 42474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "context"); 42574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 42674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 42774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 42874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 42974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 43074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 43174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (dpy == EGL_NO_DISPLAY) { 43274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: invalid current EGLDisplay"); 43374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 43474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 43574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 43674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (ctx == EGL_NO_CONTEXT) { 43774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: invalid current EGLContext"); 43874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 43974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 44074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 44174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // We need to bind the texture regardless of whether there's a current 44274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // buffer. 44374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glBindTexture(mTexTarget, tex); 44474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 44574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mCurrentTextureBuf != NULL) { 4465c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis // The EGLImageKHR that was associated with the slot was destroyed when 4472adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden // the GLConsumer was detached from the old context, so we need to 4485c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis // recreate it here. 449bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = bindUnslottedBufferLocked(dpy); 450bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 45174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return err; 45274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 45374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 45474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 45574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglDisplay = dpy; 45674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglContext = ctx; 45774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mTexName = tex; 45874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached = true; 45974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 46074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 46174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 46274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 4632adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::bindUnslottedBufferLocked(EGLDisplay dpy) { 464bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGV("bindUnslottedBuffer ct=%d ctb=%p", 465bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTexture, mCurrentTextureBuf.get()); 466bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 467bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Create a temporary EGLImageKHR. 468bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLImageKHR image = createImage(dpy, mCurrentTextureBuf); 469bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (image == EGL_NO_IMAGE_KHR) { 470bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return UNKNOWN_ERROR; 471bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 472bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 473bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Attach the current buffer to the GL texture. 474bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image); 475bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 476bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden GLint error; 477bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = OK; 478bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden while ((error = glGetError()) != GL_NO_ERROR) { 479bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("bindUnslottedBuffer: error binding external texture image %p " 480bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden "(slot %d): %#04x", image, mCurrentTexture, error); 481bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = UNKNOWN_ERROR; 482bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 483bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 484bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We destroy the EGLImageKHR here because the current buffer may no 485bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // longer be associated with one of the buffer slots, so we have 486bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // nowhere to to store it. If the buffer is still associated with a 487bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // slot then another EGLImageKHR will be created next time that buffer 488bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // gets acquired in updateTexImage. 489bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden eglDestroyImageKHR(dpy, image); 490bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 491bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 492bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 493bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 494bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 4952adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { 49674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("syncForReleaseLocked"); 49774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 49801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 499ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian if (SyncFeatures::getInstance().useNativeFenceSync()) { 50001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLSyncKHR sync = eglCreateSyncKHR(dpy, 50101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); 50201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (sync == EGL_NO_SYNC_KHR) { 50301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error creating EGL fence: %#x", 50401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglGetError()); 50574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return UNKNOWN_ERROR; 50674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 50701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis glFlush(); 50801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis int fenceFd = eglDupNativeFenceFDANDROID(dpy, sync); 50998ff0597bd9e57ba133d54f8f09841f96955cba1Jamie Gennis eglDestroySyncKHR(dpy, sync); 51001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fenceFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { 51101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error dup'ing native fence " 51201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fd: %#x", eglGetError()); 51301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 51401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 51501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis sp<Fence> fence(new Fence(fenceFd)); 516c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = addReleaseFenceLocked(mCurrentTexture, 517c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mCurrentTextureBuf, fence); 51801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (err != OK) { 51901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error adding release fence: " 52001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "%s (%d)", strerror(-err), err); 52101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return err; 52201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 523ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian } else if (mUseFenceSync && SyncFeatures::getInstance().useFenceSync()) { 52401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLSyncKHR fence = mEglSlots[mCurrentTexture].mEglFence; 52501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fence != EGL_NO_SYNC_KHR) { 52601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // There is already a fence for the current slot. We need to 52701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // wait on that before replacing it with another fence to 52801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // ensure that all outstanding buffer accesses have completed 52901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // before the producer accesses it. 53001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000); 53101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (result == EGL_FALSE) { 53201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error waiting for previous " 53301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fence: %#x", eglGetError()); 53401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 53501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 53601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: timeout waiting for previous " 53701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fence"); 53801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return TIMED_OUT; 53901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 54001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglDestroySyncKHR(dpy, fence); 54101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 54274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 54301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // Create a fence for the outstanding accesses in the current 54401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // OpenGL ES context. 54501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL); 54601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fence == EGL_NO_SYNC_KHR) { 54701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error creating fence: %#x", 54801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglGetError()); 54901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 55001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 55101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis glFlush(); 55201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis mEglSlots[mCurrentTexture].mEglFence = fence; 55374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 55474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 55574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 55674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 55774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 55874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 5592adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenbool GLConsumer::isExternalFormat(uint32_t format) 5607a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian{ 5617a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian switch (format) { 5627a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // supported YUV formats 5637a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YV12: 5647a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Legacy/deprecated YUV formats 5657a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_SP: 5667a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCrCb_420_SP: 5677a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_I: 5687a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 5697a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian } 5707a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 5717a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Any OEM format needs to be considered 5727a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian if (format>=0x100 && format<=0x1FF) 5737a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 5747a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 5757a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return false; 5767a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 5777a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 5782adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenGLenum GLConsumer::getCurrentTextureTarget() const { 579fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis return mTexTarget; 5807a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 5817a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 5822adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::getTransformMatrix(float mtx[16]) { 583f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis Mutex::Autolock lock(mMutex); 584736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix)); 585736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis} 586736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis 5872adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::setFilteringEnabled(bool enabled) { 5885c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis Mutex::Autolock lock(mMutex); 589e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (mAbandoned) { 5902adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("setFilteringEnabled: GLConsumer is abandoned!"); 591e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian return; 592e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian } 5935c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bool needsRecompute = mFilteringEnabled != enabled; 5945c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis mFilteringEnabled = enabled; 595e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 596e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (needsRecompute && mCurrentTextureBuf==NULL) { 597e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian ST_LOGD("setFilteringEnabled called with mCurrentTextureBuf == NULL"); 598e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian } 599e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 600e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (needsRecompute && mCurrentTextureBuf != NULL) { 601e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian computeCurrentTransformMatrixLocked(); 6025c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 6035c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis} 6045c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis 6052adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::computeCurrentTransformMatrixLocked() { 606e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian ST_LOGV("computeCurrentTransformMatrixLocked"); 607f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 608a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float xform[16]; 609a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 610a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = mtxIdentity[i]; 611a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 612a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) { 613a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 614a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipH); 615a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 616a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 617a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 618a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 619a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) { 620a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 621a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipV); 622a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 623a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 624a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 625a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 626a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 627a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 628a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxRot90); 629a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 630a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 631a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 632f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis } 633f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 634eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam sp<GraphicBuffer>& buf(mCurrentTextureBuf); 635e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 636e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (buf == NULL) { 637e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian ST_LOGD("computeCurrentTransformMatrixLocked: mCurrentTextureBuf is NULL"); 638e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian } 639e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 640d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis Rect cropRect = mCurrentCrop; 6415c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis float tx = 0.0f, ty = 0.0f, sx = 1.0f, sy = 1.0f; 6425c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis float bufferWidth = buf->getWidth(); 6435c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis float bufferHeight = buf->getHeight(); 644d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis if (!cropRect.isEmpty()) { 6455c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis float shrinkAmount = 0.0f; 6465c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis if (mFilteringEnabled) { 6475c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // In order to prevent bilinear sampling beyond the edge of the 6485c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // crop rectangle we may need to shrink it by 2 texels in each 6495c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // dimension. Normally this would just need to take 1/2 a texel 6505c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // off each end, but because the chroma channels of YUV420 images 6515c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // are subsampled we may need to shrink the crop region by a whole 6525c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // texel on each side. 6535c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis switch (buf->getPixelFormat()) { 6545c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGBA_8888: 6555c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGBX_8888: 6565c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGB_888: 6575c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGB_565: 6585c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_BGRA_8888: 6595c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGBA_5551: 6605c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGBA_4444: 6615c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // We know there's no subsampling of any channels, so we 6625c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // only need to shrink by a half a pixel. 6635c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis shrinkAmount = 0.5; 6644f9c284de4b9159126f69eb1219c410f66cc872cRomain Guy break; 6659fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 6665c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis default: 6675c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // If we don't recognize the format, we must assume the 6685c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // worst case (that we care about), which is YUV420. 6695c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis shrinkAmount = 1.0; 6709fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis break; 6715c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 6725c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 6735c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis 6745c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // Only shrink the dimensions that are not the size of the buffer. 6755c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis if (cropRect.width() < bufferWidth) { 6765c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis tx = (float(cropRect.left) + shrinkAmount) / bufferWidth; 6775c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis sx = (float(cropRect.width()) - (2.0f * shrinkAmount)) / 6785c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bufferWidth; 6795c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 6805c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis if (cropRect.height() < bufferHeight) { 6815c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis ty = (float(bufferHeight - cropRect.bottom) + shrinkAmount) / 6825c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bufferHeight; 6835c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis sy = (float(cropRect.height()) - (2.0f * shrinkAmount)) / 6845c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bufferHeight; 6855c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 686a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 687f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis float crop[16] = { 688a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis sx, 0, 0, 0, 689a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis 0, sy, 0, 0, 690f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 691d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis tx, ty, 0, 1, 692f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis }; 693f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 694a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float mtxBeforeFlipV[16]; 695a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(mtxBeforeFlipV, crop, xform); 696a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis 697a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // SurfaceFlinger expects the top of its window textures to be at a Y 6982adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden // coordinate of 0, so GLConsumer must behave the same way. We don't 699a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // want to expose this to applications, however, so we must add an 700a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // additional vertical flip to the transform after all the other transforms. 701736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis mtxMul(mCurrentTransformMatrix, mtxFlipV, mtxBeforeFlipV); 702f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 703f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 7042adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddennsecs_t GLConsumer::getTimestamp() { 7056ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("getTimestamp"); 7061d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala Mutex::Autolock lock(mMutex); 7071d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala return mCurrentTimestamp; 7081d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala} 7091d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala 7102adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenEGLImageKHR GLConsumer::createImage(EGLDisplay dpy, 7118ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis const sp<GraphicBuffer>& graphicBuffer) { 7128ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLClientBuffer cbuf = (EGLClientBuffer)graphicBuffer->getNativeBuffer(); 7138ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLint attrs[] = { 7148ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 7158ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_NONE, 7168ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis }; 7178ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, 7188ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs); 7193cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian if (image == EGL_NO_IMAGE_KHR) { 7203cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian EGLint error = eglGetError(); 721fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("error creating EGLImage: %#x", error); 7228ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 7238ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return image; 7248ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 7258ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 7262adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddensp<GraphicBuffer> GLConsumer::getCurrentBuffer() const { 7277a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 7287a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTextureBuf; 7297a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 7307a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7312adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenRect GLConsumer::getCurrentCrop() const { 7327a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 733016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 734016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam Rect outCrop = mCurrentCrop; 735016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { 736016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t newWidth = mCurrentCrop.width(); 737016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t newHeight = mCurrentCrop.height(); 738016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 739016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (newWidth * mDefaultHeight > newHeight * mDefaultWidth) { 740016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam newWidth = newHeight * mDefaultWidth / mDefaultHeight; 741016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ST_LOGV("too wide: newWidth = %d", newWidth); 742016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } else if (newWidth * mDefaultHeight < newHeight * mDefaultWidth) { 743016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam newHeight = newWidth * mDefaultHeight / mDefaultWidth; 744016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ST_LOGV("too tall: newHeight = %d", newHeight); 745016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 746016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 747016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The crop is too wide 748016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (newWidth < mCurrentCrop.width()) { 749016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t dw = (newWidth - mCurrentCrop.width())/2; 750016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.left -=dw; 751016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.right += dw; 752016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The crop is too tall 753016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } else if (newHeight < mCurrentCrop.height()) { 754016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t dh = (newHeight - mCurrentCrop.height())/2; 755016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.top -= dh; 756016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.bottom += dh; 757016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 758016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 759016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ST_LOGV("getCurrentCrop final crop [%d,%d,%d,%d]", 760016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.left, outCrop.top, 761016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.right,outCrop.bottom); 762016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 763016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 764016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam return outCrop; 7657a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 7667a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7672adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenuint32_t GLConsumer::getCurrentTransform() const { 7687a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 7697a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTransform; 7707a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 7717a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7722adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenuint32_t GLConsumer::getCurrentScalingMode() const { 7737734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian Mutex::Autolock lock(mMutex); 7747734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian return mCurrentScalingMode; 7757734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian} 7767734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian 7772adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddensp<Fence> GLConsumer::getCurrentFence() const { 778dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall Mutex::Autolock lock(mMutex); 779dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall return mCurrentFence; 780dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall} 781dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 7822adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::doGLFenceWait() const { 78361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis Mutex::Autolock lock(mMutex); 7843941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis return doGLFenceWaitLocked(); 7853941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis} 7863941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis 7872adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::doGLFenceWaitLocked() const { 78861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 78961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 79061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 79161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 79261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (mEglDisplay != dpy || mEglDisplay == EGL_NO_DISPLAY) { 79361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: invalid current EGLDisplay"); 79461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return INVALID_OPERATION; 79561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 79661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 79761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (mEglContext != ctx || mEglContext == EGL_NO_CONTEXT) { 79861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: invalid current EGLContext"); 79961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return INVALID_OPERATION; 80061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 80161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 8021df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis if (mCurrentFence->isValid()) { 803ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian if (SyncFeatures::getInstance().useWaitSync()) { 80461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // Create an EGLSyncKHR from the current fence. 80561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis int fenceFd = mCurrentFence->dup(); 80661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (fenceFd == -1) { 80761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: error dup'ing fence fd: %d", errno); 80861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return -errno; 80961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 81061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLint attribs[] = { 81161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd, 81261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_NONE 81361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis }; 81461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLSyncKHR sync = eglCreateSyncKHR(dpy, 81561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_SYNC_NATIVE_FENCE_ANDROID, attribs); 81661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (sync == EGL_NO_SYNC_KHR) { 81761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis close(fenceFd); 81861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: error creating EGL fence: %#x", 81961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglGetError()); 82061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return UNKNOWN_ERROR; 82161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 82261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 82361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // XXX: The spec draft is inconsistent as to whether this should 82461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // return an EGLint or void. Ignore the return value for now, as 82561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // it's not strictly needed. 8262bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian eglWaitSyncKHR(dpy, sync, 0); 82761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLint eglErr = eglGetError(); 82861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglDestroySyncKHR(dpy, sync); 82961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (eglErr != EGL_SUCCESS) { 83061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: error waiting for EGL fence: %#x", 83161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglErr); 83261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return UNKNOWN_ERROR; 83361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 83461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } else { 835ea74d3b78d607cde17790a7bb83e6f68ffd34cfdMathias Agopian status_t err = mCurrentFence->waitForever( 8362adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden "GLConsumer::doGLFenceWaitLocked"); 83761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (err != NO_ERROR) { 83861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: error waiting for fence: %d", err); 83961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return err; 84061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 84161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 84261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 84361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 84461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return NO_ERROR; 84561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis} 84661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 8472adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::freeBufferLocked(int slotIndex) { 848fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("freeBufferLocked: slotIndex=%d", slotIndex); 8499abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (slotIndex == mCurrentTexture) { 8509abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; 8519abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 8529fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis EGLImageKHR img = mEglSlots[slotIndex].mEglImage; 8539aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis if (img != EGL_NO_IMAGE_KHR) { 8549aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis ST_LOGV("destroying EGLImage dpy=%p img=%p", mEglDisplay, img); 8559aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis eglDestroyImageKHR(mEglDisplay, img); 856fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 8579fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[slotIndex].mEglImage = EGL_NO_IMAGE_KHR; 8589fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase::freeBufferLocked(slotIndex); 859fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 860fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 8612adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::abandonLocked() { 8629fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ST_LOGV("abandonLocked"); 8639fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentTextureBuf.clear(); 8649fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase::abandonLocked(); 8657b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis} 8667b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 8672adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::setName(const String8& name) { 868eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 869fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis mName = name; 870b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam mBufferQueue->setConsumerName(name); 871b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 872b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 8732adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setDefaultBufferFormat(uint32_t defaultFormat) { 874b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 875b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setDefaultBufferFormat(defaultFormat); 876b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 877b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 8782adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setConsumerUsageBits(uint32_t usage) { 879b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 88085b217668d6840c8e6a109adfb99461313676f8dEino-Ville Talvala usage |= DEFAULT_USAGE_FLAGS; 881b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setConsumerUsageBits(usage); 882b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 883b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 8842adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setTransformHint(uint32_t hint) { 885b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 886b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam return mBufferQueue->setTransformHint(hint); 887b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 888b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 88974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid GLConsumer::dumpLocked(String8& result, const char* prefix) const 89068c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian{ 89174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 8929fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis "%smTexName=%d mCurrentTexture=%d\n" 8939fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis "%smCurrentCrop=[%d,%d,%d,%d] mCurrentTransform=%#x\n", 8949fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis prefix, mTexName, mCurrentTexture, prefix, mCurrentCrop.left, 8959fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom, 8969fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentTransform); 89768c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 89874d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian ConsumerBase::dumpLocked(result, prefix); 89968c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian} 90068c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 901f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]) { 902f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3]; 903f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3]; 904f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3]; 905f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3]; 906f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 907f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7]; 908f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7]; 909f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7]; 910f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7]; 911f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 912f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11]; 913f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11]; 914f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11]; 915f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11]; 916f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 917f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15]; 918f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15]; 919f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15]; 920f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15]; 921f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 922f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 9238ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis}; // namespace android 924