GLConsumer.cpp revision 45263e2475ac6a885dbd78eff7d4e44f374e5237
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> 28ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian#include <cutils/compiler.h> 298ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 309fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis#include <hardware/hardware.h> 319fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 32ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <gui/GLConsumer.h> 3390ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/IGraphicBufferAlloc.h> 3490ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/ISurfaceComposer.h> 3590ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <gui/SurfaceComposerClient.h> 3641f673c9b3aac0d96e41c928845c39186d565212Mathias Agopian 3790ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian#include <private/gui/ComposerService.h> 38ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <private/gui/SyncFeatures.h> 398ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 408ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis#include <utils/Log.h> 4168c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian#include <utils/String8.h> 421c8e95cf86f2182986385bc1ee85f13f425f3a3aJamie Gennis#include <utils/Trace.h> 438ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 4497eba8904c2f221c42a9473407223a4c3a213f75Andy McFaddennamespace android { 4597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden 462adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden// Macros for including the GLConsumer name in log messages 476807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block#define ST_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__) 489d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block#define ST_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__) 49a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block#define ST_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__) 5032397c1cd3327905173b36baa6fd1c579bc328ffSteve Block#define ST_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__) 51e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block#define ST_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__) 5229b5762efc359022168e5099c1d17925444d3147Mathias Agopian 53ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopianstatic const struct { 54ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian size_t width, height; 55ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian char const* bits; 5645263e2475ac6a885dbd78eff7d4e44f374e5237Mathias Agopian} kDebugData = { 15, 12, 5745263e2475ac6a885dbd78eff7d4e44f374e5237Mathias Agopian "___________________________________XX_XX_______X_X_____X_X____X_XXXXXXX_X____XXXXXXXXXXX__" 5845263e2475ac6a885dbd78eff7d4e44f374e5237Mathias Agopian "___XX_XXX_XX_______XXXXXXX_________X___X_________X_____X__________________________________" 5945263e2475ac6a885dbd78eff7d4e44f374e5237Mathias Agopian}; 60ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 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 Gennis 87f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]); 88f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 89fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis 90db89edc94bd2a78226b407f9f7261e202e7fa325Mathias AgopianGLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, GLuint tex, 91595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian GLenum texTarget, bool useFenceSync, bool isControlledByApp) : 92595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian ConsumerBase(bq, isControlledByApp), 931d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTransform(0), 94e692ab9a6be63193c5b52a6562d85d06c40463b8Mathias Agopian mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 951df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis mCurrentFence(Fence::NO_FENCE), 961d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTimestamp(0), 97e692ab9a6be63193c5b52a6562d85d06c40463b8Mathias Agopian mDefaultWidth(1), 98e692ab9a6be63193c5b52a6562d85d06c40463b8Mathias Agopian mDefaultHeight(1), 995c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis mFilteringEnabled(true), 100b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mTexName(tex), 10186edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis mUseFenceSync(useFenceSync), 102eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mTexTarget(texTarget), 103ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglDisplay(EGL_NO_DISPLAY), 104ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglContext(EGL_NO_CONTEXT), 10574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), 10674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached(true) 1076b091c53000c843211c218ce40287a7edca9bc63Daniel Lam{ 1082adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGV("GLConsumer"); 109b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 110fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis memcpy(mCurrentTransformMatrix, mtxIdentity, 111fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis sizeof(mCurrentTransformMatrix)); 112fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 113db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS); 1148ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 1158ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 1162adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setDefaultMaxBufferCount(int bufferCount) { 1178072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian Mutex::Autolock lock(mMutex); 118db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setDefaultMaxBufferCount(bufferCount); 1198072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian} 1208072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 1218ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 1222adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setDefaultBufferSize(uint32_t w, uint32_t h) 123a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian{ 124b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 125016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam mDefaultWidth = w; 126016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam mDefaultHeight = h; 127db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setDefaultBufferSize(w, h); 128a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian} 129a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian 1302adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::updateTexImage() { 131bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ATRACE_CALL(); 132bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGV("updateTexImage"); 133bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden Mutex::Autolock lock(mMutex); 134bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 135bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mAbandoned) { 1362adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("updateTexImage: GLConsumer is abandoned!"); 137bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return NO_INIT; 138bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 139bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 140bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Make sure the EGL state is the same as in previous calls. 141bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = checkAndUpdateEglStateLocked(); 142bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 143bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 144bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 145bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 146bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden BufferQueue::BufferItem item; 147bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 148bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Acquire the next buffer. 149bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // In asynchronous mode the list is guaranteed to be one buffer 150bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // deep, while in synchronous mode we use the oldest buffer. 1511585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden err = acquireBufferLocked(&item, 0); 152bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 153bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 154bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We always bind the texture even if we don't update its contents. 155bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGV("updateTexImage: no buffers were available"); 156bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 157bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = NO_ERROR; 158bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } else { 159bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("updateTexImage: acquire failed: %s (%d)", 160bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden strerror(-err), err); 161bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 162bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 163bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 164bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 165bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Release the previous buffer. 166ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian err = updateAndReleaseLocked(item); 167bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 168bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We always bind the texture. 169bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 170bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 171bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 172bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 17397eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // Bind the new buffer to the GL texture, and wait until it's ready. 17497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden return bindTextureImageLocked(); 1752c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian} 1762c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 177ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 178ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopianstatus_t GLConsumer::releaseTexImage() { 179ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ATRACE_CALL(); 180ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ST_LOGV("releaseTexImage"); 181ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian Mutex::Autolock lock(mMutex); 182ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 183ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (mAbandoned) { 184ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ST_LOGE("releaseTexImage: GLConsumer is abandoned!"); 185ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return NO_INIT; 186ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 187ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 188ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian // Make sure the EGL state is the same as in previous calls. 189ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian status_t err = checkAndUpdateEglStateLocked(); 190ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (err != NO_ERROR) { 191ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return err; 192ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 193ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 194ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian // Update the GLConsumer state. 195ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian int buf = mCurrentTexture; 196ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (buf != BufferQueue::INVALID_BUFFER_SLOT) { 197ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 198ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ST_LOGV("releaseTexImage:(slot=%d", buf); 199ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 200ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian // Do whatever sync ops we need to do before releasing the slot. 201ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian err = syncForReleaseLocked(mEglDisplay); 202ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (err != NO_ERROR) { 203ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ST_LOGE("syncForReleaseLocked failed (slot=%d), err=%d", buf, err); 204ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return err; 205ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 206ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 207ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian err = releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, 208ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mEglDisplay, EGL_NO_SYNC_KHR); 209ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (err < NO_ERROR) { 210ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ST_LOGE("releaseTexImage: failed to release buffer: %s (%d)", 211ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian strerror(-err), err); 212ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return err; 213ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 214ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 215ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (CC_UNLIKELY(mReleasedTexImageBuffer == NULL)) { 216ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian // The first time, create the debug texture in case the application 217ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian // continues to use it. 21845263e2475ac6a885dbd78eff7d4e44f374e5237Mathias Agopian sp<GraphicBuffer> buffer = new GraphicBuffer( 21945263e2475ac6a885dbd78eff7d4e44f374e5237Mathias Agopian kDebugData.width, kDebugData.height, PIXEL_FORMAT_RGBA_8888, 220ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian GraphicBuffer::USAGE_SW_WRITE_RARELY); 221ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian uint32_t* bits; 222ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&bits)); 223ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian size_t w = buffer->getStride(); 224ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian size_t h = buffer->getHeight(); 225ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian memset(bits, 0, w*h*4); 226ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian for (size_t y=0 ; y<kDebugData.height ; y++) { 227ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian for (size_t x=0 ; x<kDebugData.width ; x++) { 22845263e2475ac6a885dbd78eff7d4e44f374e5237Mathias Agopian bits[x] = (kDebugData.bits[y*kDebugData.width+x] == 'X') ? 0xFF000000 : 0xFFFFFFFF; 229ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 230ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian bits += w; 231ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 232ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian buffer->unlock(); 233ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mReleasedTexImageBuffer = buffer; 234ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 235ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 236ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; 237ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentTextureBuf = mReleasedTexImageBuffer; 238ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentCrop.makeInvalid(); 239ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentTransform = 0; 240ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; 241ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentTimestamp = 0; 242ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentFence = Fence::NO_FENCE; 243ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 244ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian // bind a dummy texture 245ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian glBindTexture(mTexTarget, mTexName); 246ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian bindUnslottedBufferLocked(mEglDisplay); 247ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 248ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 249ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return NO_ERROR; 250ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian} 251ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 2521585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFaddenstatus_t GLConsumer::acquireBufferLocked(BufferQueue::BufferItem *item, 2531585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden nsecs_t presentWhen) { 2541585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen); 2559fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (err != NO_ERROR) { 2569fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return err; 2579fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 2589fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 2599fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis int slot = item->mBuf; 2609fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (item->mGraphicBuffer != NULL) { 261bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // This buffer has not been acquired before, so we must assume 262bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // that any EGLImage in mEglSlots is stale. 2639fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (mEglSlots[slot].mEglImage != EGL_NO_IMAGE_KHR) { 264bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (!eglDestroyImageKHR(mEglDisplay, mEglSlots[slot].mEglImage)) { 265bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGW("acquireBufferLocked: eglDestroyImageKHR failed for slot=%d", 266bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden slot); 267bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // keep going 268bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 2699fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[slot].mEglImage = EGL_NO_IMAGE_KHR; 2709fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 2719fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 2729fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 2739fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return NO_ERROR; 2749fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis} 2759fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 276c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnarstatus_t GLConsumer::releaseBufferLocked(int buf, 277c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar sp<GraphicBuffer> graphicBuffer, 278c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar EGLDisplay display, EGLSyncKHR eglFence) { 279c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // release the buffer if it hasn't already been discarded by the 280c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // BufferQueue. This can happen, for example, when the producer of this 281c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // buffer has reallocated the original buffer slot after this buffer 282c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // was acquired. 283c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = ConsumerBase::releaseBufferLocked( 284c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar buf, graphicBuffer, display, eglFence); 285d1b330de416adff0d178a5cb7271419d9ed7a89aJamie Gennis mEglSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 2869fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return err; 2879fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis} 2889fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 289ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopianstatus_t GLConsumer::updateAndReleaseLocked(const BufferQueue::BufferItem& item) 290bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden{ 2919abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam status_t err = NO_ERROR; 2929abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 29374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (!mAttached) { 294ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ST_LOGE("updateAndRelease: GLConsumer is not attached to an OpenGL " 29574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "ES context"); 29674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 29774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 29874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 299bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Confirm state. 300bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = checkAndUpdateEglStateLocked(); 301bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 302bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 303ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 304ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 305bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden int buf = item.mBuf; 306bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 307bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // If the mEglSlot entry is empty, create an EGLImage for the gralloc 308bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // buffer currently in the slot in ConsumerBase. 309bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // 310bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We may have to do this even when item.mGraphicBuffer == NULL (which 311bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // means the buffer was previously acquired), if we destroyed the 312bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // EGLImage when detaching from a context but the buffer has not been 313bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // re-allocated. 314bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mEglSlots[buf].mEglImage == EGL_NO_IMAGE_KHR) { 315bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLImageKHR image = createImage(mEglDisplay, mSlots[buf].mGraphicBuffer); 316bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (image == EGL_NO_IMAGE_KHR) { 317ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ST_LOGW("updateAndRelease: unable to createImage on display=%p slot=%d", 318bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglDisplay, buf); 319bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return UNKNOWN_ERROR; 320bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 321bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglSlots[buf].mEglImage = image; 322ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 323ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 324bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Do whatever sync ops we need to do before releasing the old slot. 325bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = syncForReleaseLocked(mEglDisplay); 326bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 327bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Release the buffer we just acquired. It's not safe to 328bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // release the old buffer, so instead we just drop the new frame. 329c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // As we are still under lock since acquireBuffer, it is safe to 330c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // release by slot. 331c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, 332c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mEglDisplay, EGL_NO_SYNC_KHR); 333bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 334bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 335ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 336ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ST_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", 337bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTexture, 338bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTextureBuf != NULL ? mCurrentTextureBuf->handle : 0, 339bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden buf, mSlots[buf].mGraphicBuffer->handle); 340eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 341bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // release old buffer 342bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 343c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t status = releaseBufferLocked( 344c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mCurrentTexture, mCurrentTextureBuf, mEglDisplay, 345bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglSlots[mCurrentTexture].mEglFence); 346ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (status < NO_ERROR) { 347ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ST_LOGE("updateAndRelease: failed to release buffer: %s (%d)", 348bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden strerror(-status), status); 349bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = status; 350bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // keep going, with error raised [?] 3512c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 352bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 3532c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 3542adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden // Update the GLConsumer state. 355bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTexture = buf; 356bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTextureBuf = mSlots[buf].mGraphicBuffer; 357bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentCrop = item.mCrop; 358bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTransform = item.mTransform; 359bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentScalingMode = item.mScalingMode; 360bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTimestamp = item.mTimestamp; 361bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentFence = item.mFence; 362bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 363bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden computeCurrentTransformMatrixLocked(); 364bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 365bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 366bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 367bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 3682adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::bindTextureImageLocked() { 369bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mEglDisplay == EGL_NO_DISPLAY) { 370bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ALOGE("bindTextureImage: invalid display"); 371bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 372bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 373bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 374bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden GLint error; 375bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden while ((error = glGetError()) != GL_NO_ERROR) { 376bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGW("bindTextureImage: clearing GL error: %#04x", error); 377bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 378bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 379bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 380bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT) { 381bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mCurrentTextureBuf == NULL) { 382bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("bindTextureImage: no currently-bound texture"); 383bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return NO_INIT; 3848ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 38597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden status_t err = bindUnslottedBufferLocked(mEglDisplay); 38697eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden if (err != NO_ERROR) { 38797eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden return err; 38897eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden } 389bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } else { 390bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLImageKHR image = mEglSlots[mCurrentTexture].mEglImage; 3910eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis 3929fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image); 39374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 3949fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis while ((error = glGetError()) != GL_NO_ERROR) { 395bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("bindTextureImage: error binding external texture image %p" 396bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ": %#04x", image, error); 397bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return UNKNOWN_ERROR; 3988ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 399bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 40097eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden 40197eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // Wait for the new buffer to be ready. 40297eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden return doGLFenceWaitLocked(); 40397eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden 404bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 4059a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 4062adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::checkAndUpdateEglStateLocked() { 407bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLDisplay dpy = eglGetCurrentDisplay(); 408bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLContext ctx = eglGetCurrentContext(); 40986edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis 410bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if ((mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) || 411bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden dpy == EGL_NO_DISPLAY) { 412bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("checkAndUpdateEglState: invalid current EGLDisplay"); 413bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 414bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 415b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 416bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if ((mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) || 417bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ctx == EGL_NO_CONTEXT) { 418bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("checkAndUpdateEglState: invalid current EGLContext"); 419bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 4208ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 42150c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis 422bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglDisplay = dpy; 423bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglContext = ctx; 424bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return NO_ERROR; 4258ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 4268ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 42713f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hallvoid GLConsumer::setReleaseFence(const sp<Fence>& fence) { 42813f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall if (fence->isValid() && 42913f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 430c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = addReleaseFence(mCurrentTexture, 431c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mCurrentTextureBuf, fence); 43213f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall if (err != OK) { 43313f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall ST_LOGE("setReleaseFence: failed to add the fence: %s (%d)", 43413f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall strerror(-err), err); 43513f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall } 436ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 437ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall} 438ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall 4392adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::detachFromContext() { 44074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ATRACE_CALL(); 44174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("detachFromContext"); 44274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis Mutex::Autolock lock(mMutex); 44374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 44474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAbandoned) { 4452adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("detachFromContext: abandoned GLConsumer"); 44674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return NO_INIT; 44774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 44874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 44974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (!mAttached) { 4502adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("detachFromContext: GLConsumer is not attached to a " 45174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "context"); 45274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 45374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 45474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 45574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 45674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 45774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 45874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) { 45974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: invalid current EGLDisplay"); 46074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 46174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 46274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 46374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) { 46474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: invalid current EGLContext"); 46574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 46674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 46774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 46874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (dpy != EGL_NO_DISPLAY && ctx != EGL_NO_CONTEXT) { 46974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis status_t err = syncForReleaseLocked(dpy); 47074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (err != OK) { 47174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return err; 47274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 47374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 47474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glDeleteTextures(1, &mTexName); 47574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 47674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 4779aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis // Because we're giving up the EGLDisplay we need to free all the EGLImages 4789aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis // that are associated with it. They'll be recreated when the 4792adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden // GLConsumer gets attached to a new OpenGL ES context (and thus gets a 4809aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis // new EGLDisplay). 4819aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis for (int i =0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 4829fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis EGLImageKHR img = mEglSlots[i].mEglImage; 4835c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis if (img != EGL_NO_IMAGE_KHR) { 4849aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis eglDestroyImageKHR(mEglDisplay, img); 4859fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[i].mEglImage = EGL_NO_IMAGE_KHR; 4869aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis } 4879aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis } 4889aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis 48974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglDisplay = EGL_NO_DISPLAY; 49074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglContext = EGL_NO_CONTEXT; 49174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached = false; 49274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 49374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 49474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 49574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 4962adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::attachToContext(GLuint tex) { 49774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ATRACE_CALL(); 49874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("attachToContext"); 49974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis Mutex::Autolock lock(mMutex); 50074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 50174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAbandoned) { 5022adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("attachToContext: abandoned GLConsumer"); 50374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return NO_INIT; 50474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 50574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 50674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAttached) { 5072adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("attachToContext: GLConsumer is already attached to a " 50874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "context"); 50974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 51074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 51174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 51274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 51374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 51474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 51574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (dpy == EGL_NO_DISPLAY) { 51674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: invalid current EGLDisplay"); 51774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 51874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 51974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 52074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (ctx == EGL_NO_CONTEXT) { 52174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: invalid current EGLContext"); 52274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 52374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 52474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 52574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // We need to bind the texture regardless of whether there's a current 52674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // buffer. 52774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glBindTexture(mTexTarget, tex); 52874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 52974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mCurrentTextureBuf != NULL) { 5305c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis // The EGLImageKHR that was associated with the slot was destroyed when 5312adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden // the GLConsumer was detached from the old context, so we need to 5325c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis // recreate it here. 533bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = bindUnslottedBufferLocked(dpy); 534bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 53574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return err; 53674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 53774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 53874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 53974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglDisplay = dpy; 54074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglContext = ctx; 54174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mTexName = tex; 54274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached = true; 54374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 54474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 54574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 54674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 5472adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::bindUnslottedBufferLocked(EGLDisplay dpy) { 548bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGV("bindUnslottedBuffer ct=%d ctb=%p", 549bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTexture, mCurrentTextureBuf.get()); 550bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 551bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Create a temporary EGLImageKHR. 552bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLImageKHR image = createImage(dpy, mCurrentTextureBuf); 553bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (image == EGL_NO_IMAGE_KHR) { 554bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return UNKNOWN_ERROR; 555bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 556bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 557bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Attach the current buffer to the GL texture. 558bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image); 559bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 560bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden GLint error; 561bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = OK; 562bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden while ((error = glGetError()) != GL_NO_ERROR) { 563bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("bindUnslottedBuffer: error binding external texture image %p " 564bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden "(slot %d): %#04x", image, mCurrentTexture, error); 565bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = UNKNOWN_ERROR; 566bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 567bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 568bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We destroy the EGLImageKHR here because the current buffer may no 569bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // longer be associated with one of the buffer slots, so we have 570bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // nowhere to to store it. If the buffer is still associated with a 571bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // slot then another EGLImageKHR will be created next time that buffer 572bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // gets acquired in updateTexImage. 573bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden eglDestroyImageKHR(dpy, image); 574bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 575bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 576bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 577bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 578bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 5792adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { 58074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("syncForReleaseLocked"); 58174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 58201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 583ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian if (SyncFeatures::getInstance().useNativeFenceSync()) { 58401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLSyncKHR sync = eglCreateSyncKHR(dpy, 58501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); 58601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (sync == EGL_NO_SYNC_KHR) { 58701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error creating EGL fence: %#x", 58801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglGetError()); 58974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return UNKNOWN_ERROR; 59074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 59101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis glFlush(); 59201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis int fenceFd = eglDupNativeFenceFDANDROID(dpy, sync); 59398ff0597bd9e57ba133d54f8f09841f96955cba1Jamie Gennis eglDestroySyncKHR(dpy, sync); 59401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fenceFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { 59501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error dup'ing native fence " 59601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fd: %#x", eglGetError()); 59701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 59801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 59901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis sp<Fence> fence(new Fence(fenceFd)); 600c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = addReleaseFenceLocked(mCurrentTexture, 601c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mCurrentTextureBuf, fence); 60201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (err != OK) { 60301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error adding release fence: " 60401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "%s (%d)", strerror(-err), err); 60501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return err; 60601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 607ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian } else if (mUseFenceSync && SyncFeatures::getInstance().useFenceSync()) { 60801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLSyncKHR fence = mEglSlots[mCurrentTexture].mEglFence; 60901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fence != EGL_NO_SYNC_KHR) { 61001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // There is already a fence for the current slot. We need to 61101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // wait on that before replacing it with another fence to 61201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // ensure that all outstanding buffer accesses have completed 61301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // before the producer accesses it. 61401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000); 61501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (result == EGL_FALSE) { 61601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error waiting for previous " 61701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fence: %#x", eglGetError()); 61801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 61901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 62001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: timeout waiting for previous " 62101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fence"); 62201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return TIMED_OUT; 62301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 62401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglDestroySyncKHR(dpy, fence); 62501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 62674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 62701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // Create a fence for the outstanding accesses in the current 62801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // OpenGL ES context. 62901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL); 63001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fence == EGL_NO_SYNC_KHR) { 63101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error creating fence: %#x", 63201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglGetError()); 63301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 63401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 63501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis glFlush(); 63601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis mEglSlots[mCurrentTexture].mEglFence = fence; 63774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 63874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 63974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 64074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 64174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 64274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 6432adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenbool GLConsumer::isExternalFormat(uint32_t format) 6447a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian{ 6457a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian switch (format) { 6467a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // supported YUV formats 6477a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YV12: 6487a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Legacy/deprecated YUV formats 6497a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_SP: 6507a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCrCb_420_SP: 6517a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_I: 6527a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 6537a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian } 6547a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 6557a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Any OEM format needs to be considered 6567a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian if (format>=0x100 && format<=0x1FF) 6577a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 6587a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 6597a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return false; 6607a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 6617a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 6622adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenGLenum GLConsumer::getCurrentTextureTarget() const { 663fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis return mTexTarget; 6647a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 6657a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 6662adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::getTransformMatrix(float mtx[16]) { 667f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis Mutex::Autolock lock(mMutex); 668736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix)); 669736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis} 670736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis 6712adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::setFilteringEnabled(bool enabled) { 6725c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis Mutex::Autolock lock(mMutex); 673e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (mAbandoned) { 6742adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("setFilteringEnabled: GLConsumer is abandoned!"); 675e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian return; 676e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian } 6775c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bool needsRecompute = mFilteringEnabled != enabled; 6785c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis mFilteringEnabled = enabled; 679e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 680e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (needsRecompute && mCurrentTextureBuf==NULL) { 681e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian ST_LOGD("setFilteringEnabled called with mCurrentTextureBuf == NULL"); 682e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian } 683e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 684e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (needsRecompute && mCurrentTextureBuf != NULL) { 685e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian computeCurrentTransformMatrixLocked(); 6865c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 6875c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis} 6885c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis 6892adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::computeCurrentTransformMatrixLocked() { 690e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian ST_LOGV("computeCurrentTransformMatrixLocked"); 691f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 692a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float xform[16]; 693a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 694a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = mtxIdentity[i]; 695a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 696a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) { 697a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 698a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipH); 699a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 700a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 701a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 702a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 703a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) { 704a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 705a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipV); 706a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 707a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 708a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 709a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 710a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 711a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 712a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxRot90); 713a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 714a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 715a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 716f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis } 717f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 718eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam sp<GraphicBuffer>& buf(mCurrentTextureBuf); 719e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 720e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (buf == NULL) { 721e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian ST_LOGD("computeCurrentTransformMatrixLocked: mCurrentTextureBuf is NULL"); 722e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian } 723e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 724d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis Rect cropRect = mCurrentCrop; 7255c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis float tx = 0.0f, ty = 0.0f, sx = 1.0f, sy = 1.0f; 7265c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis float bufferWidth = buf->getWidth(); 7275c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis float bufferHeight = buf->getHeight(); 728d72f233ffa125856a44976a50a66ceb669f49ab2Jamie Gennis if (!cropRect.isEmpty()) { 7295c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis float shrinkAmount = 0.0f; 7305c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis if (mFilteringEnabled) { 7315c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // In order to prevent bilinear sampling beyond the edge of the 7325c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // crop rectangle we may need to shrink it by 2 texels in each 7335c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // dimension. Normally this would just need to take 1/2 a texel 7345c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // off each end, but because the chroma channels of YUV420 images 7355c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // are subsampled we may need to shrink the crop region by a whole 7365c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // texel on each side. 7375c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis switch (buf->getPixelFormat()) { 7385c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGBA_8888: 7395c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGBX_8888: 7405c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGB_888: 7415c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_RGB_565: 7425c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis case PIXEL_FORMAT_BGRA_8888: 7435c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // We know there's no subsampling of any channels, so we 7445c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // only need to shrink by a half a pixel. 7455c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis shrinkAmount = 0.5; 7464f9c284de4b9159126f69eb1219c410f66cc872cRomain Guy break; 7479fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 7485c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis default: 7495c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // If we don't recognize the format, we must assume the 7505c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // worst case (that we care about), which is YUV420. 7515c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis shrinkAmount = 1.0; 7529fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis break; 7535c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 7545c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 7555c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis 7565c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis // Only shrink the dimensions that are not the size of the buffer. 7575c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis if (cropRect.width() < bufferWidth) { 7585c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis tx = (float(cropRect.left) + shrinkAmount) / bufferWidth; 7595c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis sx = (float(cropRect.width()) - (2.0f * shrinkAmount)) / 7605c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bufferWidth; 7615c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 7625c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis if (cropRect.height() < bufferHeight) { 7635c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis ty = (float(bufferHeight - cropRect.bottom) + shrinkAmount) / 7645c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bufferHeight; 7655c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis sy = (float(cropRect.height()) - (2.0f * shrinkAmount)) / 7665c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bufferHeight; 7675c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 768a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 769f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis float crop[16] = { 770a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis sx, 0, 0, 0, 771a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis 0, sy, 0, 0, 772f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 773d99c088f35960b7f0ef948c3bb948a99a800eba1Jamie Gennis tx, ty, 0, 1, 774f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis }; 775f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 776a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float mtxBeforeFlipV[16]; 777a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(mtxBeforeFlipV, crop, xform); 778a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis 779a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // SurfaceFlinger expects the top of its window textures to be at a Y 7802adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden // coordinate of 0, so GLConsumer must behave the same way. We don't 781a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // want to expose this to applications, however, so we must add an 782a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // additional vertical flip to the transform after all the other transforms. 783736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis mtxMul(mCurrentTransformMatrix, mtxFlipV, mtxBeforeFlipV); 784f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 785f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 7862adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddennsecs_t GLConsumer::getTimestamp() { 7876ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("getTimestamp"); 7881d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala Mutex::Autolock lock(mMutex); 7891d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala return mCurrentTimestamp; 7901d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala} 7911d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala 7922adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenEGLImageKHR GLConsumer::createImage(EGLDisplay dpy, 7938ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis const sp<GraphicBuffer>& graphicBuffer) { 7948ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLClientBuffer cbuf = (EGLClientBuffer)graphicBuffer->getNativeBuffer(); 7958ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLint attrs[] = { 7968ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 7978ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_NONE, 7988ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis }; 7998ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, 8008ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs); 8013cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian if (image == EGL_NO_IMAGE_KHR) { 8023cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian EGLint error = eglGetError(); 803fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("error creating EGLImage: %#x", error); 8048ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 8058ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return image; 8068ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 8078ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 8082adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddensp<GraphicBuffer> GLConsumer::getCurrentBuffer() const { 8097a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 8107a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTextureBuf; 8117a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 8127a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 8132adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenRect GLConsumer::getCurrentCrop() const { 8147a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 815016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 816016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam Rect outCrop = mCurrentCrop; 817016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { 818016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t newWidth = mCurrentCrop.width(); 819016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t newHeight = mCurrentCrop.height(); 820016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 821016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (newWidth * mDefaultHeight > newHeight * mDefaultWidth) { 822016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam newWidth = newHeight * mDefaultWidth / mDefaultHeight; 823016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ST_LOGV("too wide: newWidth = %d", newWidth); 824016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } else if (newWidth * mDefaultHeight < newHeight * mDefaultWidth) { 825016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam newHeight = newWidth * mDefaultHeight / mDefaultWidth; 826016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ST_LOGV("too tall: newHeight = %d", newHeight); 827016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 828016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 829016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The crop is too wide 830016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (newWidth < mCurrentCrop.width()) { 831016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t dw = (newWidth - mCurrentCrop.width())/2; 832016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.left -=dw; 833016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.right += dw; 834016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The crop is too tall 835016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } else if (newHeight < mCurrentCrop.height()) { 836016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t dh = (newHeight - mCurrentCrop.height())/2; 837016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.top -= dh; 838016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.bottom += dh; 839016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 840016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 841016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ST_LOGV("getCurrentCrop final crop [%d,%d,%d,%d]", 842016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.left, outCrop.top, 843016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.right,outCrop.bottom); 844016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 845016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 846016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam return outCrop; 8477a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 8487a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 8492adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenuint32_t GLConsumer::getCurrentTransform() const { 8507a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 8517a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTransform; 8527a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 8537a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 8542adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenuint32_t GLConsumer::getCurrentScalingMode() const { 8557734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian Mutex::Autolock lock(mMutex); 8567734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian return mCurrentScalingMode; 8577734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian} 8587734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian 8592adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddensp<Fence> GLConsumer::getCurrentFence() const { 860dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall Mutex::Autolock lock(mMutex); 861dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall return mCurrentFence; 862dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall} 863dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 8642adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::doGLFenceWait() const { 86561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis Mutex::Autolock lock(mMutex); 8663941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis return doGLFenceWaitLocked(); 8673941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis} 8683941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis 8692adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::doGLFenceWaitLocked() const { 87061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 87161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 87261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 87361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 87461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (mEglDisplay != dpy || mEglDisplay == EGL_NO_DISPLAY) { 87561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: invalid current EGLDisplay"); 87661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return INVALID_OPERATION; 87761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 87861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 87961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (mEglContext != ctx || mEglContext == EGL_NO_CONTEXT) { 88061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: invalid current EGLContext"); 88161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return INVALID_OPERATION; 88261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 88361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 8841df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis if (mCurrentFence->isValid()) { 885ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian if (SyncFeatures::getInstance().useWaitSync()) { 88661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // Create an EGLSyncKHR from the current fence. 88761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis int fenceFd = mCurrentFence->dup(); 88861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (fenceFd == -1) { 88961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: error dup'ing fence fd: %d", errno); 89061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return -errno; 89161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 89261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLint attribs[] = { 89361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd, 89461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_NONE 89561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis }; 89661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLSyncKHR sync = eglCreateSyncKHR(dpy, 89761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_SYNC_NATIVE_FENCE_ANDROID, attribs); 89861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (sync == EGL_NO_SYNC_KHR) { 89961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis close(fenceFd); 90061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: error creating EGL fence: %#x", 90161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglGetError()); 90261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return UNKNOWN_ERROR; 90361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 90461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 90561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // XXX: The spec draft is inconsistent as to whether this should 90661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // return an EGLint or void. Ignore the return value for now, as 90761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // it's not strictly needed. 9082bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian eglWaitSyncKHR(dpy, sync, 0); 90961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLint eglErr = eglGetError(); 91061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglDestroySyncKHR(dpy, sync); 91161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (eglErr != EGL_SUCCESS) { 91261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: error waiting for EGL fence: %#x", 91361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglErr); 91461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return UNKNOWN_ERROR; 91561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 91661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } else { 917ea74d3b78d607cde17790a7bb83e6f68ffd34cfdMathias Agopian status_t err = mCurrentFence->waitForever( 9182adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden "GLConsumer::doGLFenceWaitLocked"); 91961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (err != NO_ERROR) { 92061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: error waiting for fence: %d", err); 92161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return err; 92261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 92361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 92461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 92561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 92661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return NO_ERROR; 92761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis} 92861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 9292adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::freeBufferLocked(int slotIndex) { 930fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("freeBufferLocked: slotIndex=%d", slotIndex); 9319abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (slotIndex == mCurrentTexture) { 9329abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; 9339abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 9349fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis EGLImageKHR img = mEglSlots[slotIndex].mEglImage; 9359aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis if (img != EGL_NO_IMAGE_KHR) { 9369aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis ST_LOGV("destroying EGLImage dpy=%p img=%p", mEglDisplay, img); 9379aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis eglDestroyImageKHR(mEglDisplay, img); 938fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 9399fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[slotIndex].mEglImage = EGL_NO_IMAGE_KHR; 9409fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase::freeBufferLocked(slotIndex); 941fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 942fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 9432adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::abandonLocked() { 9449fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ST_LOGV("abandonLocked"); 9459fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentTextureBuf.clear(); 9469fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase::abandonLocked(); 9477b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis} 9487b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 9492adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::setName(const String8& name) { 950eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 951fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis mName = name; 952db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian mConsumer->setConsumerName(name); 953b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 954b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 9552adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setDefaultBufferFormat(uint32_t defaultFormat) { 956b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 957db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setDefaultBufferFormat(defaultFormat); 958b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 959b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 9602adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setConsumerUsageBits(uint32_t usage) { 961b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 96285b217668d6840c8e6a109adfb99461313676f8dEino-Ville Talvala usage |= DEFAULT_USAGE_FLAGS; 963db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setConsumerUsageBits(usage); 964b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 965b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 9662adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setTransformHint(uint32_t hint) { 967b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 968db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setTransformHint(hint); 969b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 970b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 97174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid GLConsumer::dumpLocked(String8& result, const char* prefix) const 97268c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian{ 97374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 9749fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis "%smTexName=%d mCurrentTexture=%d\n" 9759fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis "%smCurrentCrop=[%d,%d,%d,%d] mCurrentTransform=%#x\n", 9769fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis prefix, mTexName, mCurrentTexture, prefix, mCurrentCrop.left, 9779fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom, 9789fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentTransform); 97968c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 98074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian ConsumerBase::dumpLocked(result, prefix); 98168c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian} 98268c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 983f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]) { 984f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3]; 985f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3]; 986f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3]; 987f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3]; 988f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 989f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7]; 990f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7]; 991f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7]; 992f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7]; 993f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 994f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11]; 995f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11]; 996f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11]; 997f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11]; 998f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 999f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15]; 1000f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15]; 1001f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15]; 1002f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15]; 1003f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 1004f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 10058ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis}; // namespace android 1006