GLConsumer.cpp revision 87a678478005026d950bedec49ee80b693777b95
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 44dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie GennisEGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name); 45dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis#define CROP_EXT_STR "EGL_ANDROID_image_crop" 46dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 4797eba8904c2f221c42a9473407223a4c3a213f75Andy McFaddennamespace android { 4897eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden 492adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden// Macros for including the GLConsumer name in log messages 506807e59e0ff943cc6225d46e3c33a8a7eae9b3d7Steve Block#define ST_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__) 519d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block#define ST_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__) 52a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block#define ST_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__) 5332397c1cd3327905173b36baa6fd1c579bc328ffSteve Block#define ST_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__) 54e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block#define ST_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__) 5529b5762efc359022168e5099c1d17925444d3147Mathias Agopian 56ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopianstatic const struct { 57ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian size_t width, height; 58ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian char const* bits; 5945263e2475ac6a885dbd78eff7d4e44f374e5237Mathias Agopian} kDebugData = { 15, 12, 6045263e2475ac6a885dbd78eff7d4e44f374e5237Mathias Agopian "___________________________________XX_XX_______X_X_____X_X____X_XXXXXXX_X____XXXXXXXXXXX__" 6145263e2475ac6a885dbd78eff7d4e44f374e5237Mathias Agopian "___XX_XXX_XX_______XXXXXXX_________X___X_________X_____X__________________________________" 6245263e2475ac6a885dbd78eff7d4e44f374e5237Mathias Agopian}; 63ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 64f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis// Transform matrices 65f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxIdentity[16] = { 66f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 0, 67f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 68f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 69f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 0, 1, 70f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 71f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxFlipH[16] = { 72f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis -1, 0, 0, 0, 73f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 74f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 75f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 1, 76f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 77f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxFlipV[16] = { 78f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 0, 79f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, -1, 0, 0, 80f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 81f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 1, 82f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 83f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxRot90[16] = { 84f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 85f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis -1, 0, 0, 0, 86f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 87f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 1, 88f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 89f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 90f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]); 91f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 929870c9b66cc73ee31aabba23aa06deaf673ee5efMathias AgopianMutex GLConsumer::sStaticInitLock; 939870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopiansp<GraphicBuffer> GLConsumer::sReleasedTexImageBuffer; 94fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis 95dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennisstatic bool hasEglAndroidImageCropImpl() { 96dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 97dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis const char* exts = eglQueryStringImplementationANDROID(dpy, EGL_EXTENSIONS); 98dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis size_t cropExtLen = strlen(CROP_EXT_STR); 99dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis size_t extsLen = strlen(exts); 100dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bool equal = !strcmp(CROP_EXT_STR, exts); 101dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bool atStart = !strncmp(CROP_EXT_STR " ", exts, cropExtLen+1); 102dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bool atEnd = (cropExtLen+1) < extsLen && 103dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis !strcmp(" " CROP_EXT_STR, exts + extsLen - (cropExtLen+1)); 104dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bool inMiddle = strstr(exts, " " CROP_EXT_STR " "); 105dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis return equal || atStart || atEnd || inMiddle; 106dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis} 107dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 108dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennisstatic bool hasEglAndroidImageCrop() { 109dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // Only compute whether the extension is present once the first time this 110dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // function is called. 111dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis static bool hasIt = hasEglAndroidImageCropImpl(); 112dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis return hasIt; 113dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis} 114dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 115dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennisstatic bool isEglImageCroppable(const Rect& crop) { 116dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis return hasEglAndroidImageCrop() && (crop.left == 0 && crop.top == 0); 117dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis} 118dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 1193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias AgopianGLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex, 1203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian uint32_t texTarget, bool useFenceSync, bool isControlledByApp) : 121595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian ConsumerBase(bq, isControlledByApp), 1221d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTransform(0), 123e692ab9a6be63193c5b52a6562d85d06c40463b8Mathias Agopian mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 1241df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis mCurrentFence(Fence::NO_FENCE), 1251d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTimestamp(0), 126d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala mCurrentFrameNumber(0), 127e692ab9a6be63193c5b52a6562d85d06c40463b8Mathias Agopian mDefaultWidth(1), 128e692ab9a6be63193c5b52a6562d85d06c40463b8Mathias Agopian mDefaultHeight(1), 1295c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis mFilteringEnabled(true), 130b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mTexName(tex), 13186edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis mUseFenceSync(useFenceSync), 132eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mTexTarget(texTarget), 133ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglDisplay(EGL_NO_DISPLAY), 134ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglContext(EGL_NO_CONTEXT), 13574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), 13674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached(true) 1376b091c53000c843211c218ce40287a7edca9bc63Daniel Lam{ 1382adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGV("GLConsumer"); 139b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 140fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis memcpy(mCurrentTransformMatrix, mtxIdentity, 141fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis sizeof(mCurrentTransformMatrix)); 142fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 143db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS); 1448ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 1458ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 1462adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setDefaultMaxBufferCount(int bufferCount) { 1478072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian Mutex::Autolock lock(mMutex); 148db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setDefaultMaxBufferCount(bufferCount); 1498072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian} 1508072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 1518ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 1522adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setDefaultBufferSize(uint32_t w, uint32_t h) 153a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian{ 154b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 155016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam mDefaultWidth = w; 156016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam mDefaultHeight = h; 157db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setDefaultBufferSize(w, h); 158a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian} 159a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian 1602adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::updateTexImage() { 161bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ATRACE_CALL(); 162bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGV("updateTexImage"); 163bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden Mutex::Autolock lock(mMutex); 164bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 165bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mAbandoned) { 1662adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("updateTexImage: GLConsumer is abandoned!"); 167bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return NO_INIT; 168bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 169bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 170bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Make sure the EGL state is the same as in previous calls. 171bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = checkAndUpdateEglStateLocked(); 172bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 173bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 174bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 175bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 176bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden BufferQueue::BufferItem item; 177bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 178bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Acquire the next buffer. 179bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // In asynchronous mode the list is guaranteed to be one buffer 180bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // deep, while in synchronous mode we use the oldest buffer. 1811585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden err = acquireBufferLocked(&item, 0); 182bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 183bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 184bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We always bind the texture even if we don't update its contents. 185bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGV("updateTexImage: no buffers were available"); 186bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 187bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = NO_ERROR; 188bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } else { 189bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("updateTexImage: acquire failed: %s (%d)", 190bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden strerror(-err), err); 191bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 192bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 193bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 194bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 195bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Release the previous buffer. 196ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian err = updateAndReleaseLocked(item); 197bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 198bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We always bind the texture. 199bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 200bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 201bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 202bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 20397eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // Bind the new buffer to the GL texture, and wait until it's ready. 20497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden return bindTextureImageLocked(); 2052c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian} 2062c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 207ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 208ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopianstatus_t GLConsumer::releaseTexImage() { 209ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ATRACE_CALL(); 210ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ST_LOGV("releaseTexImage"); 211ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian Mutex::Autolock lock(mMutex); 212ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 213ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (mAbandoned) { 214ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ST_LOGE("releaseTexImage: GLConsumer is abandoned!"); 215ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return NO_INIT; 216ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 217ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 218ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian // Make sure the EGL state is the same as in previous calls. 21945155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian status_t err = NO_ERROR; 22045155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian 22145155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mAttached) { 22245155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian err = checkAndUpdateEglStateLocked(true); 22345155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (err != NO_ERROR) { 22445155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian return err; 22545155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 22645155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } else { 22745155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // if we're detached, no need to validate EGL's state -- we won't use it. 228ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 229ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 230ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian // Update the GLConsumer state. 231ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian int buf = mCurrentTexture; 232ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (buf != BufferQueue::INVALID_BUFFER_SLOT) { 233ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 23445155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian ST_LOGV("releaseTexImage: (slot=%d, mAttached=%d)", buf, mAttached); 235ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 23645155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mAttached) { 23745155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // Do whatever sync ops we need to do before releasing the slot. 23845155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian err = syncForReleaseLocked(mEglDisplay); 23945155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (err != NO_ERROR) { 24045155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian ST_LOGE("syncForReleaseLocked failed (slot=%d), err=%d", buf, err); 24145155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian return err; 24245155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 24345155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } else { 24445155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // if we're detached, we just use the fence that was created in detachFromContext() 24545155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // so... basically, nothing more to do here. 246ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 247ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 24845155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian err = releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, mEglDisplay, EGL_NO_SYNC_KHR); 249ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (err < NO_ERROR) { 250ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ST_LOGE("releaseTexImage: failed to release buffer: %s (%d)", 251ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian strerror(-err), err); 252ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return err; 253ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 254ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 255ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; 2569870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian mCurrentTextureBuf = getDebugTexImageBuffer(); 257ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentCrop.makeInvalid(); 258ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentTransform = 0; 259ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; 260ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentTimestamp = 0; 261ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentFence = Fence::NO_FENCE; 262ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 26345155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mAttached) { 26445155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // bind a dummy texture 26545155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian glBindTexture(mTexTarget, mTexName); 26645155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian bindUnslottedBufferLocked(mEglDisplay); 26745155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } else { 26845155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // detached, don't touch the texture (and we may not even have an 26945155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // EGLDisplay here. 27045155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 271ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 272ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 273ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return NO_ERROR; 274ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian} 275ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 2769870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopiansp<GraphicBuffer> GLConsumer::getDebugTexImageBuffer() { 2779870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian Mutex::Autolock _l(sStaticInitLock); 2789870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian if (CC_UNLIKELY(sReleasedTexImageBuffer == NULL)) { 2799870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian // The first time, create the debug texture in case the application 2809870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian // continues to use it. 2819870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian sp<GraphicBuffer> buffer = new GraphicBuffer( 2829870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian kDebugData.width, kDebugData.height, PIXEL_FORMAT_RGBA_8888, 2839870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian GraphicBuffer::USAGE_SW_WRITE_RARELY); 2849870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian uint32_t* bits; 2859870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&bits)); 2869870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian size_t w = buffer->getStride(); 2879870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian size_t h = buffer->getHeight(); 2889870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian memset(bits, 0, w*h*4); 2899870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian for (size_t y=0 ; y<kDebugData.height ; y++) { 2909870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian for (size_t x=0 ; x<kDebugData.width ; x++) { 2919870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian bits[x] = (kDebugData.bits[y*kDebugData.width+x] == 'X') ? 0xFF000000 : 0xFFFFFFFF; 2929870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian } 2939870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian bits += w; 2949870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian } 2959870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian buffer->unlock(); 2969870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian sReleasedTexImageBuffer = buffer; 2979870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian } 2989870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian return sReleasedTexImageBuffer; 2999870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian} 3009870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian 3011585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFaddenstatus_t GLConsumer::acquireBufferLocked(BufferQueue::BufferItem *item, 3021585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden nsecs_t presentWhen) { 3031585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen); 3049fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (err != NO_ERROR) { 3059fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return err; 3069fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 3079fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 3089fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis int slot = item->mBuf; 309dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bool destroyEglImage = false; 310dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 311dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis if (mEglSlots[slot].mEglImage != EGL_NO_IMAGE_KHR) { 312dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis if (item->mGraphicBuffer != NULL) { 313dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // This buffer has not been acquired before, so we must assume 314dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // that any EGLImage in mEglSlots is stale. 315dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis destroyEglImage = true; 316dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis } else if (mEglSlots[slot].mCropRect != item->mCrop) { 317dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // We've already seen this buffer before, but it now has a 318dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // different crop rect, so we'll need to recreate the EGLImage if 319dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // we're using the EGL_ANDROID_image_crop extension. 320dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis destroyEglImage = hasEglAndroidImageCrop(); 321dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis } 322dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis } 323dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 324dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis if (destroyEglImage) { 325dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis if (!eglDestroyImageKHR(mEglDisplay, mEglSlots[slot].mEglImage)) { 326dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis ST_LOGW("acquireBufferLocked: eglDestroyImageKHR failed for slot=%d", 327dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis slot); 328dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // keep going 3299fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 330dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis mEglSlots[slot].mEglImage = EGL_NO_IMAGE_KHR; 3319fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 3329fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 3339fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return NO_ERROR; 3349fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis} 3359fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 336c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnarstatus_t GLConsumer::releaseBufferLocked(int buf, 337c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar sp<GraphicBuffer> graphicBuffer, 338c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar EGLDisplay display, EGLSyncKHR eglFence) { 339c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // release the buffer if it hasn't already been discarded by the 340c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // BufferQueue. This can happen, for example, when the producer of this 341c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // buffer has reallocated the original buffer slot after this buffer 342c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // was acquired. 343c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = ConsumerBase::releaseBufferLocked( 344c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar buf, graphicBuffer, display, eglFence); 345d1b330de416adff0d178a5cb7271419d9ed7a89aJamie Gennis mEglSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 3469fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return err; 3479fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis} 3489fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 349ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopianstatus_t GLConsumer::updateAndReleaseLocked(const BufferQueue::BufferItem& item) 350bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden{ 3519abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam status_t err = NO_ERROR; 3529abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 35387a678478005026d950bedec49ee80b693777b95Andy McFadden int buf = item.mBuf; 35487a678478005026d950bedec49ee80b693777b95Andy McFadden 35574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (!mAttached) { 356ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ST_LOGE("updateAndRelease: GLConsumer is not attached to an OpenGL " 35774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "ES context"); 35887a678478005026d950bedec49ee80b693777b95Andy McFadden releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, 35987a678478005026d950bedec49ee80b693777b95Andy McFadden mEglDisplay, EGL_NO_SYNC_KHR); 36074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 36174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 36274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 363bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Confirm state. 364bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = checkAndUpdateEglStateLocked(); 365bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 36687a678478005026d950bedec49ee80b693777b95Andy McFadden releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, 36787a678478005026d950bedec49ee80b693777b95Andy McFadden mEglDisplay, EGL_NO_SYNC_KHR); 368bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 369ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 370ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 371bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // If the mEglSlot entry is empty, create an EGLImage for the gralloc 372bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // buffer currently in the slot in ConsumerBase. 373bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // 374bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We may have to do this even when item.mGraphicBuffer == NULL (which 375bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // means the buffer was previously acquired), if we destroyed the 376bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // EGLImage when detaching from a context but the buffer has not been 377bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // re-allocated. 378bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mEglSlots[buf].mEglImage == EGL_NO_IMAGE_KHR) { 379dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis EGLImageKHR image = createImage(mEglDisplay, 380dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis mSlots[buf].mGraphicBuffer, item.mCrop); 381bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (image == EGL_NO_IMAGE_KHR) { 382ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ST_LOGW("updateAndRelease: unable to createImage on display=%p slot=%d", 383bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglDisplay, buf); 38487a678478005026d950bedec49ee80b693777b95Andy McFadden const sp<GraphicBuffer>& gb = mSlots[buf].mGraphicBuffer; 38587a678478005026d950bedec49ee80b693777b95Andy McFadden ST_LOGW("buffer size=%ux%u st=%u usage=0x%x fmt=%d", 38687a678478005026d950bedec49ee80b693777b95Andy McFadden gb->getWidth(), gb->getHeight(), gb->getStride(), 38787a678478005026d950bedec49ee80b693777b95Andy McFadden gb->getUsage(), gb->getPixelFormat()); 38887a678478005026d950bedec49ee80b693777b95Andy McFadden releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, 38987a678478005026d950bedec49ee80b693777b95Andy McFadden mEglDisplay, EGL_NO_SYNC_KHR); 390bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return UNKNOWN_ERROR; 391bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 392bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglSlots[buf].mEglImage = image; 393dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis mEglSlots[buf].mCropRect = item.mCrop; 394ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 395ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 396bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Do whatever sync ops we need to do before releasing the old slot. 397bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = syncForReleaseLocked(mEglDisplay); 398bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 399bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Release the buffer we just acquired. It's not safe to 400bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // release the old buffer, so instead we just drop the new frame. 401c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // As we are still under lock since acquireBuffer, it is safe to 402c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // release by slot. 403c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, 404c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mEglDisplay, EGL_NO_SYNC_KHR); 405bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 406bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 407ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 408ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ST_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", 409bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTexture, 410bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTextureBuf != NULL ? mCurrentTextureBuf->handle : 0, 411bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden buf, mSlots[buf].mGraphicBuffer->handle); 412eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 413bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // release old buffer 414bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 415c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t status = releaseBufferLocked( 416c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mCurrentTexture, mCurrentTextureBuf, mEglDisplay, 417bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglSlots[mCurrentTexture].mEglFence); 418ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (status < NO_ERROR) { 419ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ST_LOGE("updateAndRelease: failed to release buffer: %s (%d)", 420bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden strerror(-status), status); 421bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = status; 422bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // keep going, with error raised [?] 4232c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 424bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 4252c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 4262adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden // Update the GLConsumer state. 427bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTexture = buf; 428bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTextureBuf = mSlots[buf].mGraphicBuffer; 429bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentCrop = item.mCrop; 430bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTransform = item.mTransform; 431bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentScalingMode = item.mScalingMode; 432bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTimestamp = item.mTimestamp; 433bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentFence = item.mFence; 434d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala mCurrentFrameNumber = item.mFrameNumber; 435bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 436bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden computeCurrentTransformMatrixLocked(); 437bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 438bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 439bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 440bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 4412adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::bindTextureImageLocked() { 442bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mEglDisplay == EGL_NO_DISPLAY) { 443bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ALOGE("bindTextureImage: invalid display"); 444bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 445bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 446bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 447bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden GLint error; 448bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden while ((error = glGetError()) != GL_NO_ERROR) { 449bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGW("bindTextureImage: clearing GL error: %#04x", error); 450bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 451bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 452bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 453bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT) { 454bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mCurrentTextureBuf == NULL) { 455bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("bindTextureImage: no currently-bound texture"); 456bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return NO_INIT; 4578ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 45897eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden status_t err = bindUnslottedBufferLocked(mEglDisplay); 45997eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden if (err != NO_ERROR) { 46097eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden return err; 46197eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden } 462bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } else { 463bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLImageKHR image = mEglSlots[mCurrentTexture].mEglImage; 4640eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis 4659fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image); 46674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 4679fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis while ((error = glGetError()) != GL_NO_ERROR) { 468bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("bindTextureImage: error binding external texture image %p" 469bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ": %#04x", image, error); 470bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return UNKNOWN_ERROR; 4718ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 472bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 47397eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden 47497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // Wait for the new buffer to be ready. 47597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden return doGLFenceWaitLocked(); 47697eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden 477bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 4789a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 47945155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopianstatus_t GLConsumer::checkAndUpdateEglStateLocked(bool contextCheck) { 480bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLDisplay dpy = eglGetCurrentDisplay(); 481bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLContext ctx = eglGetCurrentContext(); 48286edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis 48345155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (!contextCheck) { 48445155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // if this is the first time we're called, mEglDisplay/mEglContext have 48545155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // never been set, so don't error out (below). 48645155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mEglDisplay == EGL_NO_DISPLAY) { 48745155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian mEglDisplay = dpy; 48845155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 48945155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mEglContext == EGL_NO_DISPLAY) { 49045155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian mEglContext = ctx; 49145155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 49245155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 49345155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian 49445155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mEglDisplay != dpy || dpy == EGL_NO_DISPLAY) { 495bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("checkAndUpdateEglState: invalid current EGLDisplay"); 496bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 497bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 498b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 49945155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mEglContext != ctx || ctx == EGL_NO_CONTEXT) { 500bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("checkAndUpdateEglState: invalid current EGLContext"); 501bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 5028ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 50350c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis 504bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglDisplay = dpy; 505bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglContext = ctx; 506bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return NO_ERROR; 5078ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 5088ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 50913f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hallvoid GLConsumer::setReleaseFence(const sp<Fence>& fence) { 51013f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall if (fence->isValid() && 51113f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 512c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = addReleaseFence(mCurrentTexture, 513c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mCurrentTextureBuf, fence); 51413f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall if (err != OK) { 51513f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall ST_LOGE("setReleaseFence: failed to add the fence: %s (%d)", 51613f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall strerror(-err), err); 51713f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall } 518ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 519ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall} 520ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall 5212adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::detachFromContext() { 52274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ATRACE_CALL(); 52374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("detachFromContext"); 52474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis Mutex::Autolock lock(mMutex); 52574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 52674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAbandoned) { 5272adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("detachFromContext: abandoned GLConsumer"); 52874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return NO_INIT; 52974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 53074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 53174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (!mAttached) { 5322adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("detachFromContext: GLConsumer is not attached to a " 53374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "context"); 53474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 53574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 53674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 53774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 53874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 53974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 54074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) { 54174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: invalid current EGLDisplay"); 54274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 54374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 54474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 54574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) { 54674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("detachFromContext: invalid current EGLContext"); 54774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 54874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 54974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 55074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (dpy != EGL_NO_DISPLAY && ctx != EGL_NO_CONTEXT) { 55174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis status_t err = syncForReleaseLocked(dpy); 55274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (err != OK) { 55374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return err; 55474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 55574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 55674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glDeleteTextures(1, &mTexName); 55774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 55874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 5599aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis // Because we're giving up the EGLDisplay we need to free all the EGLImages 5609aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis // that are associated with it. They'll be recreated when the 5612adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden // GLConsumer gets attached to a new OpenGL ES context (and thus gets a 5629aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis // new EGLDisplay). 5639aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis for (int i =0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 5649fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis EGLImageKHR img = mEglSlots[i].mEglImage; 5655c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis if (img != EGL_NO_IMAGE_KHR) { 5669aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis eglDestroyImageKHR(mEglDisplay, img); 5679fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[i].mEglImage = EGL_NO_IMAGE_KHR; 5689aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis } 5699aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis } 5709aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis 57174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglDisplay = EGL_NO_DISPLAY; 57274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglContext = EGL_NO_CONTEXT; 57374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached = false; 57474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 57574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 57674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 57774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 5783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianstatus_t GLConsumer::attachToContext(uint32_t tex) { 57974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ATRACE_CALL(); 58074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("attachToContext"); 58174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis Mutex::Autolock lock(mMutex); 58274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 58374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAbandoned) { 5842adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("attachToContext: abandoned GLConsumer"); 58574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return NO_INIT; 58674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 58774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 58874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAttached) { 5892adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("attachToContext: GLConsumer is already attached to a " 59074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "context"); 59174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 59274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 59374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 59474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 59574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 59674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 59774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (dpy == EGL_NO_DISPLAY) { 59874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: invalid current EGLDisplay"); 59974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 60074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 60174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 60274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (ctx == EGL_NO_CONTEXT) { 60374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGE("attachToContext: invalid current EGLContext"); 60474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 60574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 60674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 60774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // We need to bind the texture regardless of whether there's a current 60874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // buffer. 6093f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian glBindTexture(mTexTarget, GLuint(tex)); 61074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 61174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mCurrentTextureBuf != NULL) { 6125c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis // The EGLImageKHR that was associated with the slot was destroyed when 6132adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden // the GLConsumer was detached from the old context, so we need to 6145c8a608497f12ecea4d6e8f1f286baf57c161ea3Jamie Gennis // recreate it here. 615bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = bindUnslottedBufferLocked(dpy); 616bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 61774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return err; 61874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 61974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 62074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 62174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglDisplay = dpy; 62274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglContext = ctx; 62374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mTexName = tex; 62474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached = true; 62574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 62674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 62774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 62874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 6292adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::bindUnslottedBufferLocked(EGLDisplay dpy) { 630bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGV("bindUnslottedBuffer ct=%d ctb=%p", 631bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTexture, mCurrentTextureBuf.get()); 632bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 633bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Create a temporary EGLImageKHR. 634dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis Rect crop; 635dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis EGLImageKHR image = createImage(dpy, mCurrentTextureBuf, mCurrentCrop); 636bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (image == EGL_NO_IMAGE_KHR) { 637bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return UNKNOWN_ERROR; 638bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 639bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 640bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Attach the current buffer to the GL texture. 641bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image); 642bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 643bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden GLint error; 644bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = OK; 645bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden while ((error = glGetError()) != GL_NO_ERROR) { 646bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ST_LOGE("bindUnslottedBuffer: error binding external texture image %p " 647bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden "(slot %d): %#04x", image, mCurrentTexture, error); 648bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = UNKNOWN_ERROR; 649bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 650bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 651bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We destroy the EGLImageKHR here because the current buffer may no 652bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // longer be associated with one of the buffer slots, so we have 653bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // nowhere to to store it. If the buffer is still associated with a 654bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // slot then another EGLImageKHR will be created next time that buffer 655bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // gets acquired in updateTexImage. 656bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden eglDestroyImageKHR(dpy, image); 657bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 658bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 659bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 660bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 661bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 6622adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { 66374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ST_LOGV("syncForReleaseLocked"); 66474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 66501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 666ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian if (SyncFeatures::getInstance().useNativeFenceSync()) { 66701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLSyncKHR sync = eglCreateSyncKHR(dpy, 66801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); 66901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (sync == EGL_NO_SYNC_KHR) { 67001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error creating EGL fence: %#x", 67101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglGetError()); 67274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return UNKNOWN_ERROR; 67374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 67401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis glFlush(); 67501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis int fenceFd = eglDupNativeFenceFDANDROID(dpy, sync); 67698ff0597bd9e57ba133d54f8f09841f96955cba1Jamie Gennis eglDestroySyncKHR(dpy, sync); 67701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fenceFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { 67801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error dup'ing native fence " 67901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fd: %#x", eglGetError()); 68001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 68101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 68201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis sp<Fence> fence(new Fence(fenceFd)); 683c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = addReleaseFenceLocked(mCurrentTexture, 684c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mCurrentTextureBuf, fence); 68501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (err != OK) { 68601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error adding release fence: " 68701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "%s (%d)", strerror(-err), err); 68801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return err; 68901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 690ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian } else if (mUseFenceSync && SyncFeatures::getInstance().useFenceSync()) { 69101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLSyncKHR fence = mEglSlots[mCurrentTexture].mEglFence; 69201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fence != EGL_NO_SYNC_KHR) { 69301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // There is already a fence for the current slot. We need to 69401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // wait on that before replacing it with another fence to 69501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // ensure that all outstanding buffer accesses have completed 69601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // before the producer accesses it. 69701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000); 69801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (result == EGL_FALSE) { 69901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error waiting for previous " 70001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fence: %#x", eglGetError()); 70101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 70201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 70301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: timeout waiting for previous " 70401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fence"); 70501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return TIMED_OUT; 70601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 70701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglDestroySyncKHR(dpy, fence); 70801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 70974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 71001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // Create a fence for the outstanding accesses in the current 71101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // OpenGL ES context. 71201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL); 71301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fence == EGL_NO_SYNC_KHR) { 71401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis ST_LOGE("syncForReleaseLocked: error creating fence: %#x", 71501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglGetError()); 71601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 71701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 71801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis glFlush(); 71901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis mEglSlots[mCurrentTexture].mEglFence = fence; 72074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 72174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 72274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 72374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 72474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 72574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 7262adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenbool GLConsumer::isExternalFormat(uint32_t format) 7277a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian{ 7287a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian switch (format) { 7297a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // supported YUV formats 7307a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YV12: 7317a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Legacy/deprecated YUV formats 7327a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_SP: 7337a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCrCb_420_SP: 7347a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_I: 7357a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 7367a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian } 7377a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7387a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Any OEM format needs to be considered 7397a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian if (format>=0x100 && format<=0x1FF) 7407a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 7417a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7427a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return false; 7437a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 7447a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t GLConsumer::getCurrentTextureTarget() const { 746fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis return mTexTarget; 7477a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 7487a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7492adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::getTransformMatrix(float mtx[16]) { 750f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis Mutex::Autolock lock(mMutex); 751736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix)); 752736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis} 753736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis 7542adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::setFilteringEnabled(bool enabled) { 7555c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis Mutex::Autolock lock(mMutex); 756e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (mAbandoned) { 7572adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden ST_LOGE("setFilteringEnabled: GLConsumer is abandoned!"); 758e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian return; 759e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian } 7605c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bool needsRecompute = mFilteringEnabled != enabled; 7615c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis mFilteringEnabled = enabled; 762e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 763e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (needsRecompute && mCurrentTextureBuf==NULL) { 764e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian ST_LOGD("setFilteringEnabled called with mCurrentTextureBuf == NULL"); 765e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian } 766e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 767e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (needsRecompute && mCurrentTextureBuf != NULL) { 768e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian computeCurrentTransformMatrixLocked(); 7695c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 7705c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis} 7715c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis 7722adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::computeCurrentTransformMatrixLocked() { 773e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian ST_LOGV("computeCurrentTransformMatrixLocked"); 774f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 775a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float xform[16]; 776a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 777a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = mtxIdentity[i]; 778a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 779a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) { 780a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 781a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipH); 782a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 783a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 784a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 785a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 786a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) { 787a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 788a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipV); 789a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 790a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 791a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 792a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 793a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 794a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 795a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxRot90); 796a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 797a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 798a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 799f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis } 800f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 801eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam sp<GraphicBuffer>& buf(mCurrentTextureBuf); 802e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 803e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (buf == NULL) { 804e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian ST_LOGD("computeCurrentTransformMatrixLocked: mCurrentTextureBuf is NULL"); 805e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian } 806e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 807dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis float mtxBeforeFlipV[16]; 808dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis if (!isEglImageCroppable(mCurrentCrop)) { 809dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis Rect cropRect = mCurrentCrop; 810dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis float tx = 0.0f, ty = 0.0f, sx = 1.0f, sy = 1.0f; 811dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis float bufferWidth = buf->getWidth(); 812dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis float bufferHeight = buf->getHeight(); 813dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis if (!cropRect.isEmpty()) { 814dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis float shrinkAmount = 0.0f; 815dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis if (mFilteringEnabled) { 816dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // In order to prevent bilinear sampling beyond the edge of the 817dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // crop rectangle we may need to shrink it by 2 texels in each 818dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // dimension. Normally this would just need to take 1/2 a texel 819dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // off each end, but because the chroma channels of YUV420 images 820dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // are subsampled we may need to shrink the crop region by a whole 821dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // texel on each side. 822dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis switch (buf->getPixelFormat()) { 823dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis case PIXEL_FORMAT_RGBA_8888: 824dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis case PIXEL_FORMAT_RGBX_8888: 825dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis case PIXEL_FORMAT_RGB_888: 826dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis case PIXEL_FORMAT_RGB_565: 827dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis case PIXEL_FORMAT_BGRA_8888: 828dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // We know there's no subsampling of any channels, so we 829dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // only need to shrink by a half a pixel. 830dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis shrinkAmount = 0.5; 831dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis break; 832dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 833dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis default: 834dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // If we don't recognize the format, we must assume the 835dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // worst case (that we care about), which is YUV420. 836dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis shrinkAmount = 1.0; 837dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis break; 838dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis } 8395c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 8405c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis 841dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // Only shrink the dimensions that are not the size of the buffer. 842dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis if (cropRect.width() < bufferWidth) { 843dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis tx = (float(cropRect.left) + shrinkAmount) / bufferWidth; 844dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis sx = (float(cropRect.width()) - (2.0f * shrinkAmount)) / 845dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bufferWidth; 846dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis } 847dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis if (cropRect.height() < bufferHeight) { 848dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis ty = (float(bufferHeight - cropRect.bottom) + shrinkAmount) / 849dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bufferHeight; 850dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis sy = (float(cropRect.height()) - (2.0f * shrinkAmount)) / 851dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bufferHeight; 852dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis } 8535c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 854dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis float crop[16] = { 855dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis sx, 0, 0, 0, 856dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 0, sy, 0, 0, 857dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 0, 0, 1, 0, 858dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis tx, ty, 0, 1, 859dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis }; 860dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 861dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis mtxMul(mtxBeforeFlipV, crop, xform); 862dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis } else { 863dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis for (int i = 0; i < 16; i++) { 864dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis mtxBeforeFlipV[i] = xform[i]; 8655c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 866a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 867a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis 868a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // SurfaceFlinger expects the top of its window textures to be at a Y 8692adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden // coordinate of 0, so GLConsumer must behave the same way. We don't 870a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // want to expose this to applications, however, so we must add an 871a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // additional vertical flip to the transform after all the other transforms. 872736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis mtxMul(mCurrentTransformMatrix, mtxFlipV, mtxBeforeFlipV); 873f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 874f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 8752adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddennsecs_t GLConsumer::getTimestamp() { 8766ee96ad6a3da260f2473f78ea0582fd0970cf156Jamie Gennis ST_LOGV("getTimestamp"); 8771d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala Mutex::Autolock lock(mMutex); 8781d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala return mCurrentTimestamp; 8791d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala} 8801d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala 881d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvalansecs_t GLConsumer::getFrameNumber() { 882d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala ST_LOGV("getFrameNumber"); 883d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala Mutex::Autolock lock(mMutex); 884d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala return mCurrentFrameNumber; 885d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala} 886d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala 8872adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenEGLImageKHR GLConsumer::createImage(EGLDisplay dpy, 888dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis const sp<GraphicBuffer>& graphicBuffer, const Rect& crop) { 8898ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLClientBuffer cbuf = (EGLClientBuffer)graphicBuffer->getNativeBuffer(); 8908ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLint attrs[] = { 891dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 892dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis EGL_IMAGE_CROP_LEFT_ANDROID, crop.left, 893dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis EGL_IMAGE_CROP_TOP_ANDROID, crop.top, 894dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis EGL_IMAGE_CROP_RIGHT_ANDROID, crop.right, 895dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis EGL_IMAGE_CROP_BOTTOM_ANDROID, crop.bottom, 8968ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_NONE, 8978ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis }; 898dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis if (!crop.isValid()) { 899dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // No crop rect to set, so terminate the attrib array before the crop. 900dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis attrs[2] = EGL_NONE; 901dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis } else if (!isEglImageCroppable(crop)) { 902dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // The crop rect is not at the origin, so we can't set the crop on the 903dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // EGLImage because that's not allowed by the EGL_ANDROID_image_crop 904dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // extension. In the future we can add a layered extension that 905dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // removes this restriction if there is hardware that can support it. 906dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis attrs[2] = EGL_NONE; 907dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis } 9088ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, 9098ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs); 9103cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian if (image == EGL_NO_IMAGE_KHR) { 9113cd5a117083e6a53b9946e8c316377658ab79b3dMathias Agopian EGLint error = eglGetError(); 912fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis ST_LOGE("error creating EGLImage: %#x", error); 9138ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 9148ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis return image; 9158ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 9168ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 9172adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddensp<GraphicBuffer> GLConsumer::getCurrentBuffer() const { 9187a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 9197a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTextureBuf; 9207a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 9217a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 9222adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenRect GLConsumer::getCurrentCrop() const { 9237a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 924016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 925016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam Rect outCrop = mCurrentCrop; 926016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { 927016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t newWidth = mCurrentCrop.width(); 928016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t newHeight = mCurrentCrop.height(); 929016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 930016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (newWidth * mDefaultHeight > newHeight * mDefaultWidth) { 931016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam newWidth = newHeight * mDefaultWidth / mDefaultHeight; 932016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ST_LOGV("too wide: newWidth = %d", newWidth); 933016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } else if (newWidth * mDefaultHeight < newHeight * mDefaultWidth) { 934016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam newHeight = newWidth * mDefaultHeight / mDefaultWidth; 935016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ST_LOGV("too tall: newHeight = %d", newHeight); 936016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 937016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 938016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The crop is too wide 939016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (newWidth < mCurrentCrop.width()) { 940016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t dw = (newWidth - mCurrentCrop.width())/2; 941016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.left -=dw; 942016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.right += dw; 943016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The crop is too tall 944016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } else if (newHeight < mCurrentCrop.height()) { 945016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam int32_t dh = (newHeight - mCurrentCrop.height())/2; 946016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.top -= dh; 947016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.bottom += dh; 948016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 949016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 950016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam ST_LOGV("getCurrentCrop final crop [%d,%d,%d,%d]", 951016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.left, outCrop.top, 952016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.right,outCrop.bottom); 953016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 954016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 955016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam return outCrop; 9567a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 9577a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 9582adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenuint32_t GLConsumer::getCurrentTransform() const { 9597a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 9607a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTransform; 9617a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 9627a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 9632adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenuint32_t GLConsumer::getCurrentScalingMode() const { 9647734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian Mutex::Autolock lock(mMutex); 9657734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian return mCurrentScalingMode; 9667734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian} 9677734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian 9682adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddensp<Fence> GLConsumer::getCurrentFence() const { 969dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall Mutex::Autolock lock(mMutex); 970dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall return mCurrentFence; 971dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall} 972dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 9732adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::doGLFenceWait() const { 97461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis Mutex::Autolock lock(mMutex); 9753941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis return doGLFenceWaitLocked(); 9763941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis} 9773941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis 9782adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::doGLFenceWaitLocked() const { 97961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 98061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 98161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 98261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 98361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (mEglDisplay != dpy || mEglDisplay == EGL_NO_DISPLAY) { 98461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: invalid current EGLDisplay"); 98561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return INVALID_OPERATION; 98661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 98761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 98861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (mEglContext != ctx || mEglContext == EGL_NO_CONTEXT) { 98961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: invalid current EGLContext"); 99061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return INVALID_OPERATION; 99161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 99261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 9931df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis if (mCurrentFence->isValid()) { 994ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian if (SyncFeatures::getInstance().useWaitSync()) { 99561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // Create an EGLSyncKHR from the current fence. 99661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis int fenceFd = mCurrentFence->dup(); 99761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (fenceFd == -1) { 99861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: error dup'ing fence fd: %d", errno); 99961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return -errno; 100061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 100161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLint attribs[] = { 100261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd, 100361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_NONE 100461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis }; 100561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLSyncKHR sync = eglCreateSyncKHR(dpy, 100661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_SYNC_NATIVE_FENCE_ANDROID, attribs); 100761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (sync == EGL_NO_SYNC_KHR) { 100861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis close(fenceFd); 100961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: error creating EGL fence: %#x", 101061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglGetError()); 101161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return UNKNOWN_ERROR; 101261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 101361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 101461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // XXX: The spec draft is inconsistent as to whether this should 101561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // return an EGLint or void. Ignore the return value for now, as 101661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // it's not strictly needed. 10172bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian eglWaitSyncKHR(dpy, sync, 0); 101861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLint eglErr = eglGetError(); 101961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglDestroySyncKHR(dpy, sync); 102061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (eglErr != EGL_SUCCESS) { 102161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: error waiting for EGL fence: %#x", 102261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglErr); 102361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return UNKNOWN_ERROR; 102461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 102561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } else { 1026ea74d3b78d607cde17790a7bb83e6f68ffd34cfdMathias Agopian status_t err = mCurrentFence->waitForever( 10272adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden "GLConsumer::doGLFenceWaitLocked"); 102861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (err != NO_ERROR) { 102961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis ST_LOGE("doGLFenceWait: error waiting for fence: %d", err); 103061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return err; 103161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 103261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 103361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 103461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 103561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return NO_ERROR; 103661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis} 103761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 10382adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::freeBufferLocked(int slotIndex) { 1039fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis ST_LOGV("freeBufferLocked: slotIndex=%d", slotIndex); 10409abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (slotIndex == mCurrentTexture) { 10419abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; 10429abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 10439fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis EGLImageKHR img = mEglSlots[slotIndex].mEglImage; 10449aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis if (img != EGL_NO_IMAGE_KHR) { 10459aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis ST_LOGV("destroying EGLImage dpy=%p img=%p", mEglDisplay, img); 10469aa74dbc7070aa396bc425ea3feae3d26e5393f6Jamie Gennis eglDestroyImageKHR(mEglDisplay, img); 1047fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis } 10489fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mEglSlots[slotIndex].mEglImage = EGL_NO_IMAGE_KHR; 10499fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase::freeBufferLocked(slotIndex); 1050fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 1051fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 10522adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::abandonLocked() { 10539fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ST_LOGV("abandonLocked"); 10549fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentTextureBuf.clear(); 10559fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase::abandonLocked(); 10567b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis} 10577b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 10582adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::setName(const String8& name) { 1059eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 1060fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis mName = name; 1061db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian mConsumer->setConsumerName(name); 1062b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 1063b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 10642adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setDefaultBufferFormat(uint32_t defaultFormat) { 1065b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 1066db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setDefaultBufferFormat(defaultFormat); 1067b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 1068b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 10692adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setConsumerUsageBits(uint32_t usage) { 1070b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 107185b217668d6840c8e6a109adfb99461313676f8dEino-Ville Talvala usage |= DEFAULT_USAGE_FLAGS; 1072db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setConsumerUsageBits(usage); 1073b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 1074b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 10752adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setTransformHint(uint32_t hint) { 1076b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 1077db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setTransformHint(hint); 1078b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 1079b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 108074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid GLConsumer::dumpLocked(String8& result, const char* prefix) const 108168c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian{ 108274d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 10839fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis "%smTexName=%d mCurrentTexture=%d\n" 10849fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis "%smCurrentCrop=[%d,%d,%d,%d] mCurrentTransform=%#x\n", 10859fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis prefix, mTexName, mCurrentTexture, prefix, mCurrentCrop.left, 10869fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom, 10879fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentTransform); 108868c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 108974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian ConsumerBase::dumpLocked(result, prefix); 109068c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian} 109168c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 1092f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]) { 1093f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3]; 1094f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3]; 1095f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3]; 1096f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3]; 1097f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1098f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7]; 1099f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7]; 1100f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7]; 1101f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7]; 1102f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1103f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11]; 1104f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11]; 1105f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11]; 1106f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11]; 1107f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1108f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15]; 1109f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15]; 1110f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15]; 1111f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15]; 1112f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 1113f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 11148ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis}; // namespace android 1115