GLConsumer.cpp revision d723bd7669b4fc88dc282d8bf8ba5ecb2849d22f
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 50d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza#define GLC_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__) 51d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza#define GLC_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__) 52d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza//#define GLC_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__) 53d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza#define GLC_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__) 54d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza#define GLC_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__) 5529b5762efc359022168e5099c1d17925444d3147Mathias Agopian 56ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopianstatic const struct { 57d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza uint32_t width, height; 58ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian char const* bits; 5945263e2475ac6a885dbd78eff7d4e44f374e5237Mathias Agopian} kDebugData = { 15, 12, 60d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "_______________" 61d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "_______________" 62d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "_____XX_XX_____" 63d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "__X_X_____X_X__" 64d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "__X_XXXXXXX_X__" 65d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "__XXXXXXXXXXX__" 66d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "___XX_XXX_XX___" 67d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "____XXXXXXX____" 68d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "_____X___X_____" 69d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "____X_____X____" 70d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "_______________" 71d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "_______________" 7245263e2475ac6a885dbd78eff7d4e44f374e5237Mathias Agopian}; 73ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 74f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis// Transform matrices 75f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxIdentity[16] = { 76f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 0, 77f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 78f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 79f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 0, 1, 80f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 81f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxFlipH[16] = { 82f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis -1, 0, 0, 0, 83f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 84f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 85f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 1, 86f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 87f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxFlipV[16] = { 88f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 0, 89f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, -1, 0, 0, 90f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 91f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 1, 92f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 93f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxRot90[16] = { 94f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 95f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis -1, 0, 0, 0, 96f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 97f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 1, 98f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 99f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 100f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]); 101f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1029870c9b66cc73ee31aabba23aa06deaf673ee5efMathias AgopianMutex GLConsumer::sStaticInitLock; 1039870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopiansp<GraphicBuffer> GLConsumer::sReleasedTexImageBuffer; 104fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis 105dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennisstatic bool hasEglAndroidImageCropImpl() { 106dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 107dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis const char* exts = eglQueryStringImplementationANDROID(dpy, EGL_EXTENSIONS); 108dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis size_t cropExtLen = strlen(CROP_EXT_STR); 109dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis size_t extsLen = strlen(exts); 110dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bool equal = !strcmp(CROP_EXT_STR, exts); 111dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bool atStart = !strncmp(CROP_EXT_STR " ", exts, cropExtLen+1); 112dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bool atEnd = (cropExtLen+1) < extsLen && 113dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis !strcmp(" " CROP_EXT_STR, exts + extsLen - (cropExtLen+1)); 114dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bool inMiddle = strstr(exts, " " CROP_EXT_STR " "); 115dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis return equal || atStart || atEnd || inMiddle; 116dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis} 117dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 118dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennisstatic bool hasEglAndroidImageCrop() { 119dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // Only compute whether the extension is present once the first time this 120dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // function is called. 121dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis static bool hasIt = hasEglAndroidImageCropImpl(); 122dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis return hasIt; 123dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis} 124dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 125dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennisstatic bool isEglImageCroppable(const Rect& crop) { 126dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis return hasEglAndroidImageCrop() && (crop.left == 0 && crop.top == 0); 127dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis} 128dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 1293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias AgopianGLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex, 1303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian uint32_t texTarget, bool useFenceSync, bool isControlledByApp) : 131595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian ConsumerBase(bq, isControlledByApp), 1321d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTransform(0), 133e692ab9a6be63193c5b52a6562d85d06c40463b8Mathias Agopian mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 1341df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis mCurrentFence(Fence::NO_FENCE), 1351d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTimestamp(0), 136d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala mCurrentFrameNumber(0), 137e692ab9a6be63193c5b52a6562d85d06c40463b8Mathias Agopian mDefaultWidth(1), 138e692ab9a6be63193c5b52a6562d85d06c40463b8Mathias Agopian mDefaultHeight(1), 1395c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis mFilteringEnabled(true), 140b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mTexName(tex), 14186edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis mUseFenceSync(useFenceSync), 142eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mTexTarget(texTarget), 143ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglDisplay(EGL_NO_DISPLAY), 144ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglContext(EGL_NO_CONTEXT), 14574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), 14674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached(true) 1476b091c53000c843211c218ce40287a7edca9bc63Daniel Lam{ 148d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("GLConsumer"); 149b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 150fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis memcpy(mCurrentTransformMatrix, mtxIdentity, 151fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis sizeof(mCurrentTransformMatrix)); 152fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 153db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS); 1548ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 1558ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 156ab57491de3a89a2d454d3060d36adef71741a7aeDan StozaGLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t texTarget, 157ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza bool useFenceSync, bool isControlledByApp) : 158ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza ConsumerBase(bq, isControlledByApp), 159ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mCurrentTransform(0), 160ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 161ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mCurrentFence(Fence::NO_FENCE), 162ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mCurrentTimestamp(0), 163ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mCurrentFrameNumber(0), 164ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mDefaultWidth(1), 165ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mDefaultHeight(1), 166ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mFilteringEnabled(true), 167d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza mTexName(0), 168ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mUseFenceSync(useFenceSync), 169ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mTexTarget(texTarget), 170ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mEglDisplay(EGL_NO_DISPLAY), 171ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mEglContext(EGL_NO_CONTEXT), 172ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), 173ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mAttached(false) 174ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza{ 175d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("GLConsumer"); 176ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza 177ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza memcpy(mCurrentTransformMatrix, mtxIdentity, 178ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza sizeof(mCurrentTransformMatrix)); 179ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza 180ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS); 181ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza} 182ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza 1832adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setDefaultMaxBufferCount(int bufferCount) { 1848072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian Mutex::Autolock lock(mMutex); 185db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setDefaultMaxBufferCount(bufferCount); 1868072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian} 1878072711307aa98ee5ee6f7369860ae38c3e19656Mathias Agopian 1888ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 1892adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setDefaultBufferSize(uint32_t w, uint32_t h) 190a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian{ 191b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 192016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam mDefaultWidth = w; 193016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam mDefaultHeight = h; 194db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setDefaultBufferSize(w, h); 195a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian} 196a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian 1972adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::updateTexImage() { 198bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ATRACE_CALL(); 199d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("updateTexImage"); 200bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden Mutex::Autolock lock(mMutex); 201bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 202bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mAbandoned) { 203d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("updateTexImage: GLConsumer is abandoned!"); 204bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return NO_INIT; 205bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 206bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 207bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Make sure the EGL state is the same as in previous calls. 208bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = checkAndUpdateEglStateLocked(); 209bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 210bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 211bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 212bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 213bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden BufferQueue::BufferItem item; 214bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 215bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Acquire the next buffer. 216bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // In asynchronous mode the list is guaranteed to be one buffer 217bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // deep, while in synchronous mode we use the oldest buffer. 2181585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden err = acquireBufferLocked(&item, 0); 219bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 220bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 221bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We always bind the texture even if we don't update its contents. 222d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("updateTexImage: no buffers were available"); 223bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 224bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = NO_ERROR; 225bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } else { 226d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("updateTexImage: acquire failed: %s (%d)", 227bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden strerror(-err), err); 228bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 229bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 230bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 231bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 232bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Release the previous buffer. 233ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian err = updateAndReleaseLocked(item); 234bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 235bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We always bind the texture. 236bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 237bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 238bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 239bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 24097eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // Bind the new buffer to the GL texture, and wait until it's ready. 24197eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden return bindTextureImageLocked(); 2422c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian} 2432c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 244ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 245ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopianstatus_t GLConsumer::releaseTexImage() { 246ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ATRACE_CALL(); 247d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("releaseTexImage"); 248ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian Mutex::Autolock lock(mMutex); 249ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 250ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (mAbandoned) { 251d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("releaseTexImage: GLConsumer is abandoned!"); 252ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return NO_INIT; 253ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 254ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 255ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian // Make sure the EGL state is the same as in previous calls. 25645155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian status_t err = NO_ERROR; 25745155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian 25845155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mAttached) { 25945155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian err = checkAndUpdateEglStateLocked(true); 26045155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (err != NO_ERROR) { 26145155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian return err; 26245155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 26345155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } else { 26445155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // if we're detached, no need to validate EGL's state -- we won't use it. 265ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 266ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 267ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian // Update the GLConsumer state. 268ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian int buf = mCurrentTexture; 269ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (buf != BufferQueue::INVALID_BUFFER_SLOT) { 270ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 271d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("releaseTexImage: (slot=%d, mAttached=%d)", buf, mAttached); 272ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 27345155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mAttached) { 27445155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // Do whatever sync ops we need to do before releasing the slot. 27545155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian err = syncForReleaseLocked(mEglDisplay); 27645155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (err != NO_ERROR) { 277d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("syncForReleaseLocked failed (slot=%d), err=%d", buf, err); 27845155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian return err; 27945155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 28045155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } else { 28145155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // if we're detached, we just use the fence that was created in detachFromContext() 28245155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // so... basically, nothing more to do here. 283ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 284ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 28545155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian err = releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, mEglDisplay, EGL_NO_SYNC_KHR); 286ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (err < NO_ERROR) { 287d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("releaseTexImage: failed to release buffer: %s (%d)", 288ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian strerror(-err), err); 289ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return err; 290ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 291ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 2925c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (mReleasedTexImage == NULL) { 2935c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mReleasedTexImage = new EglImage(getDebugTexImageBuffer()); 2945c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 2955c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 296ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; 2975c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTextureImage = mReleasedTexImage; 298ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentCrop.makeInvalid(); 299ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentTransform = 0; 300ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; 301ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentTimestamp = 0; 302ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentFence = Fence::NO_FENCE; 303ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 30445155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mAttached) { 3055c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // This binds a dummy buffer (mReleasedTexImage). 306d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza status_t result = bindTextureImageLocked(); 307d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza if (result != NO_ERROR) { 308d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza return result; 3095c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 31045155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } else { 31145155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // detached, don't touch the texture (and we may not even have an 31245155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // EGLDisplay here. 31345155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 314ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 315ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 316ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return NO_ERROR; 317ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian} 318ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 3199870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopiansp<GraphicBuffer> GLConsumer::getDebugTexImageBuffer() { 3209870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian Mutex::Autolock _l(sStaticInitLock); 3219870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian if (CC_UNLIKELY(sReleasedTexImageBuffer == NULL)) { 3229870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian // The first time, create the debug texture in case the application 3239870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian // continues to use it. 3249870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian sp<GraphicBuffer> buffer = new GraphicBuffer( 3259870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian kDebugData.width, kDebugData.height, PIXEL_FORMAT_RGBA_8888, 3269870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian GraphicBuffer::USAGE_SW_WRITE_RARELY); 3279870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian uint32_t* bits; 3289870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&bits)); 329d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza uint32_t stride = buffer->getStride(); 330d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza uint32_t height = buffer->getHeight(); 331d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza memset(bits, 0, stride * height * 4); 332d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza for (uint32_t y = 0; y < kDebugData.height; y++) { 333d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza for (uint32_t x = 0; x < kDebugData.width; x++) { 334d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza bits[x] = (kDebugData.bits[y + kDebugData.width + x] == 'X') ? 335d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza 0xFF000000 : 0xFFFFFFFF; 3369870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian } 337d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza bits += stride; 3389870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian } 3399870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian buffer->unlock(); 3409870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian sReleasedTexImageBuffer = buffer; 3419870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian } 3429870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian return sReleasedTexImageBuffer; 3439870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian} 3449870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian 3451585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFaddenstatus_t GLConsumer::acquireBufferLocked(BufferQueue::BufferItem *item, 3461585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden nsecs_t presentWhen) { 3471585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen); 3489fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (err != NO_ERROR) { 3499fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return err; 3509fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 3519fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 3525c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // If item->mGraphicBuffer is not null, this buffer has not been acquired 3535c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // before, so any prior EglImage created is using a stale buffer. This 3545c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // replaces any old EglImage with a new one (using the new buffer). 3555c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (item->mGraphicBuffer != NULL) { 3565c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner int slot = item->mBuf; 3575c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglSlots[slot].mEglImage = new EglImage(item->mGraphicBuffer); 3589fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 3599fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 3609fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return NO_ERROR; 3619fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis} 3629fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 363c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnarstatus_t GLConsumer::releaseBufferLocked(int buf, 364c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar sp<GraphicBuffer> graphicBuffer, 365c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar EGLDisplay display, EGLSyncKHR eglFence) { 366c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // release the buffer if it hasn't already been discarded by the 367c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // BufferQueue. This can happen, for example, when the producer of this 368c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // buffer has reallocated the original buffer slot after this buffer 369c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // was acquired. 370c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = ConsumerBase::releaseBufferLocked( 371c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar buf, graphicBuffer, display, eglFence); 372d1b330de416adff0d178a5cb7271419d9ed7a89aJamie Gennis mEglSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 3739fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return err; 3749fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis} 3759fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 376ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopianstatus_t GLConsumer::updateAndReleaseLocked(const BufferQueue::BufferItem& item) 377bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden{ 3789abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam status_t err = NO_ERROR; 3799abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 38087a678478005026d950bedec49ee80b693777b95Andy McFadden int buf = item.mBuf; 38187a678478005026d950bedec49ee80b693777b95Andy McFadden 38274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (!mAttached) { 383d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("updateAndRelease: GLConsumer is not attached to an OpenGL " 38474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "ES context"); 38587a678478005026d950bedec49ee80b693777b95Andy McFadden releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, 38687a678478005026d950bedec49ee80b693777b95Andy McFadden mEglDisplay, EGL_NO_SYNC_KHR); 38774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 38874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 38974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 390bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Confirm state. 391bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = checkAndUpdateEglStateLocked(); 392bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 39387a678478005026d950bedec49ee80b693777b95Andy McFadden releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, 39487a678478005026d950bedec49ee80b693777b95Andy McFadden mEglDisplay, EGL_NO_SYNC_KHR); 395bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 396ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 397ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 3985c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // Ensure we have a valid EglImageKHR for the slot, creating an EglImage 3995c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // if nessessary, for the gralloc buffer currently in the slot in 4005c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // ConsumerBase. 401bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We may have to do this even when item.mGraphicBuffer == NULL (which 4025c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // means the buffer was previously acquired). 4035c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner err = mEglSlots[buf].mEglImage->createIfNeeded(mEglDisplay, item.mCrop); 4045c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (err != NO_ERROR) { 405d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGW("updateAndRelease: unable to createImage on display=%p slot=%d", 4065c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglDisplay, buf); 4075c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, 4085c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglDisplay, EGL_NO_SYNC_KHR); 4095c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner return UNKNOWN_ERROR; 410ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 411ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 412bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Do whatever sync ops we need to do before releasing the old slot. 413bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = syncForReleaseLocked(mEglDisplay); 414bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 415bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Release the buffer we just acquired. It's not safe to 416bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // release the old buffer, so instead we just drop the new frame. 417c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // As we are still under lock since acquireBuffer, it is safe to 418c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // release by slot. 419c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, 420c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar mEglDisplay, EGL_NO_SYNC_KHR); 421bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 422bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 423ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 424d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", 4255c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTexture, mCurrentTextureImage != NULL ? 4265c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTextureImage->graphicBufferHandle() : 0, 427bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden buf, mSlots[buf].mGraphicBuffer->handle); 428eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 429bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // release old buffer 430bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 431c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t status = releaseBufferLocked( 4325c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTexture, mCurrentTextureImage->graphicBuffer(), 4335c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglDisplay, mEglSlots[mCurrentTexture].mEglFence); 434ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (status < NO_ERROR) { 435d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)", 436bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden strerror(-status), status); 437bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = status; 438bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // keep going, with error raised [?] 4392c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 440bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 4412c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 4422adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden // Update the GLConsumer state. 443bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTexture = buf; 4445c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTextureImage = mEglSlots[buf].mEglImage; 445bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentCrop = item.mCrop; 446bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTransform = item.mTransform; 447bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentScalingMode = item.mScalingMode; 448bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTimestamp = item.mTimestamp; 449bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentFence = item.mFence; 450d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala mCurrentFrameNumber = item.mFrameNumber; 451bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 452bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden computeCurrentTransformMatrixLocked(); 453bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 454bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 455bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 456bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 4572adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::bindTextureImageLocked() { 458bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mEglDisplay == EGL_NO_DISPLAY) { 459bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ALOGE("bindTextureImage: invalid display"); 460bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 461bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 462bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 463d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLenum error; 464bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden while ((error = glGetError()) != GL_NO_ERROR) { 465d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGW("bindTextureImage: clearing GL error: %#04x", error); 466bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 467bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 468bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 4695c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && 4705c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTextureImage == NULL) { 471d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("bindTextureImage: no currently-bound texture"); 4725c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner return NO_INIT; 4735c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 4740eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis 4755c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner status_t err = mCurrentTextureImage->createIfNeeded(mEglDisplay, 4762d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner mCurrentCrop); 4775c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (err != NO_ERROR) { 478d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGW("bindTextureImage: can't create image on display=%p slot=%d", 4795c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglDisplay, mCurrentTexture); 4805c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner return UNKNOWN_ERROR; 4815c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 4825c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTextureImage->bindToTextureTarget(mTexTarget); 4835c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 4842d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner // In the rare case that the display is terminated and then initialized 4852d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner // again, we can't detect that the display changed (it didn't), but the 4862d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner // image is invalid. In this case, repeat the exact same steps while 4872d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner // forcing the creation of a new image. 4882d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner if ((error = glGetError()) != GL_NO_ERROR) { 4892d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner glBindTexture(mTexTarget, mTexName); 490d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza status_t result = mCurrentTextureImage->createIfNeeded(mEglDisplay, 491d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza mCurrentCrop, 492d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza true); 493d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza if (result != NO_ERROR) { 494d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGW("bindTextureImage: can't create image on display=%p slot=%d", 4952d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner mEglDisplay, mCurrentTexture); 4962d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner return UNKNOWN_ERROR; 4972d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner } 4982d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner mCurrentTextureImage->bindToTextureTarget(mTexTarget); 4992d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner if ((error = glGetError()) != GL_NO_ERROR) { 500d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("bindTextureImage: error binding external image: %#04x", error); 5012d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner return UNKNOWN_ERROR; 5022d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner } 503bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 50497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden 50597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // Wait for the new buffer to be ready. 50697eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden return doGLFenceWaitLocked(); 507bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 5089a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 50945155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopianstatus_t GLConsumer::checkAndUpdateEglStateLocked(bool contextCheck) { 510bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLDisplay dpy = eglGetCurrentDisplay(); 511bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLContext ctx = eglGetCurrentContext(); 51286edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis 51345155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (!contextCheck) { 51445155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // if this is the first time we're called, mEglDisplay/mEglContext have 51545155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // never been set, so don't error out (below). 51645155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mEglDisplay == EGL_NO_DISPLAY) { 51745155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian mEglDisplay = dpy; 51845155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 51946a1f6b40e1f7677cd41cd30f729ff66c7c21517Jesse Hall if (mEglContext == EGL_NO_CONTEXT) { 52045155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian mEglContext = ctx; 52145155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 52245155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 52345155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian 52445155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mEglDisplay != dpy || dpy == EGL_NO_DISPLAY) { 525d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("checkAndUpdateEglState: invalid current EGLDisplay"); 526bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 527bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 528b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 52945155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mEglContext != ctx || ctx == EGL_NO_CONTEXT) { 530d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("checkAndUpdateEglState: invalid current EGLContext"); 531bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 5328ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 53350c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis 534bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglDisplay = dpy; 535bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglContext = ctx; 536bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return NO_ERROR; 5378ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 5388ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 53913f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hallvoid GLConsumer::setReleaseFence(const sp<Fence>& fence) { 54013f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall if (fence->isValid() && 54113f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 542c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = addReleaseFence(mCurrentTexture, 5435c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTextureImage->graphicBuffer(), fence); 54413f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall if (err != OK) { 545d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("setReleaseFence: failed to add the fence: %s (%d)", 54613f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall strerror(-err), err); 54713f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall } 548ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 549ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall} 550ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall 5512adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::detachFromContext() { 55274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ATRACE_CALL(); 553d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("detachFromContext"); 55474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis Mutex::Autolock lock(mMutex); 55574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 55674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAbandoned) { 557d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("detachFromContext: abandoned GLConsumer"); 55874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return NO_INIT; 55974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 56074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 56174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (!mAttached) { 562d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("detachFromContext: GLConsumer is not attached to a " 56374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "context"); 56474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 56574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 56674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 56774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 56874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 56974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 57074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) { 571d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("detachFromContext: invalid current EGLDisplay"); 57274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 57374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 57474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 57574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) { 576d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("detachFromContext: invalid current EGLContext"); 57774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 57874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 57974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 58074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (dpy != EGL_NO_DISPLAY && ctx != EGL_NO_CONTEXT) { 58174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis status_t err = syncForReleaseLocked(dpy); 58274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (err != OK) { 58374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return err; 58474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 58574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 58674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glDeleteTextures(1, &mTexName); 58774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 58874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 58974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglDisplay = EGL_NO_DISPLAY; 59074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglContext = EGL_NO_CONTEXT; 59174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached = false; 59274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 59374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 59474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 59574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 5963f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianstatus_t GLConsumer::attachToContext(uint32_t tex) { 59774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ATRACE_CALL(); 598d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("attachToContext"); 59974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis Mutex::Autolock lock(mMutex); 60074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 60174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAbandoned) { 602d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("attachToContext: abandoned GLConsumer"); 60374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return NO_INIT; 60474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 60574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 60674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAttached) { 607d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("attachToContext: GLConsumer is already attached to a " 60874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "context"); 60974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 61074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 61174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 61274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 61374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 61474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 61574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (dpy == EGL_NO_DISPLAY) { 616d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("attachToContext: invalid current EGLDisplay"); 61774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 61874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 61974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 62074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (ctx == EGL_NO_CONTEXT) { 621d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("attachToContext: invalid current EGLContext"); 62274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 62374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 62474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 62574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // We need to bind the texture regardless of whether there's a current 62674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // buffer. 6273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian glBindTexture(mTexTarget, GLuint(tex)); 62874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 62974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglDisplay = dpy; 63074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglContext = ctx; 63174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mTexName = tex; 63274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached = true; 63374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 6345c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (mCurrentTextureImage != NULL) { 6355c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // This may wait for a buffer a second time. This is likely required if 6365c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // this is a different context, since otherwise the wait could be skipped 6375c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // by bouncing through another context. For the same context the extra 6385c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // wait is redundant. 6395c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner status_t err = bindTextureImageLocked(); 6405c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (err != NO_ERROR) { 6415c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner return err; 6425c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 643bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 644bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 6455c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner return OK; 646bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 647bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 648bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 6492adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { 650d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("syncForReleaseLocked"); 65174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 65201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 653ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian if (SyncFeatures::getInstance().useNativeFenceSync()) { 65401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLSyncKHR sync = eglCreateSyncKHR(dpy, 65501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); 65601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (sync == EGL_NO_SYNC_KHR) { 657d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("syncForReleaseLocked: error creating EGL fence: %#x", 65801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglGetError()); 65974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return UNKNOWN_ERROR; 66074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 66101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis glFlush(); 66201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis int fenceFd = eglDupNativeFenceFDANDROID(dpy, sync); 66398ff0597bd9e57ba133d54f8f09841f96955cba1Jamie Gennis eglDestroySyncKHR(dpy, sync); 66401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fenceFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { 665d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("syncForReleaseLocked: error dup'ing native fence " 66601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fd: %#x", eglGetError()); 66701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 66801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 66901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis sp<Fence> fence(new Fence(fenceFd)); 670c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = addReleaseFenceLocked(mCurrentTexture, 6715c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTextureImage->graphicBuffer(), fence); 67201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (err != OK) { 673d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("syncForReleaseLocked: error adding release fence: " 67401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "%s (%d)", strerror(-err), err); 67501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return err; 67601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 677ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian } else if (mUseFenceSync && SyncFeatures::getInstance().useFenceSync()) { 67801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLSyncKHR fence = mEglSlots[mCurrentTexture].mEglFence; 67901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fence != EGL_NO_SYNC_KHR) { 68001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // There is already a fence for the current slot. We need to 68101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // wait on that before replacing it with another fence to 68201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // ensure that all outstanding buffer accesses have completed 68301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // before the producer accesses it. 68401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000); 68501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (result == EGL_FALSE) { 686d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("syncForReleaseLocked: error waiting for previous " 68701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fence: %#x", eglGetError()); 68801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 68901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 690d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("syncForReleaseLocked: timeout waiting for previous " 69101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fence"); 69201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return TIMED_OUT; 69301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 69401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglDestroySyncKHR(dpy, fence); 69501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 69674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 69701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // Create a fence for the outstanding accesses in the current 69801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // OpenGL ES context. 69901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL); 70001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fence == EGL_NO_SYNC_KHR) { 701d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("syncForReleaseLocked: error creating fence: %#x", 70201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglGetError()); 70301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 70401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 70501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis glFlush(); 70601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis mEglSlots[mCurrentTexture].mEglFence = fence; 70774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 70874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 70974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 71074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 71174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 71274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 713d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stozabool GLConsumer::isExternalFormat(PixelFormat format) 7147a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian{ 7157a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian switch (format) { 7167a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // supported YUV formats 7177a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YV12: 7187a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Legacy/deprecated YUV formats 7197a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_SP: 7207a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCrCb_420_SP: 7217a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_I: 7227a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 7237a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian } 7247a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7257a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Any OEM format needs to be considered 7267a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian if (format>=0x100 && format<=0x1FF) 7277a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 7287a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7297a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return false; 7307a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 7317a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t GLConsumer::getCurrentTextureTarget() const { 733fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis return mTexTarget; 7347a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 7357a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7362adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::getTransformMatrix(float mtx[16]) { 737f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis Mutex::Autolock lock(mMutex); 738736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix)); 739736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis} 740736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis 7412adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::setFilteringEnabled(bool enabled) { 7425c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis Mutex::Autolock lock(mMutex); 743e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (mAbandoned) { 744d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("setFilteringEnabled: GLConsumer is abandoned!"); 745e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian return; 746e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian } 7475c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bool needsRecompute = mFilteringEnabled != enabled; 7485c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis mFilteringEnabled = enabled; 749e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 7505c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (needsRecompute && mCurrentTextureImage==NULL) { 751d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGD("setFilteringEnabled called with mCurrentTextureImage == NULL"); 752e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian } 753e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 7545c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (needsRecompute && mCurrentTextureImage != NULL) { 755e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian computeCurrentTransformMatrixLocked(); 7565c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 7575c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis} 7585c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis 7592adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::computeCurrentTransformMatrixLocked() { 760d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("computeCurrentTransformMatrixLocked"); 761f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 762a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float xform[16]; 763a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 764a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = mtxIdentity[i]; 765a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 766a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) { 767a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 768a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipH); 769a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 770a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 771a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 772a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 773a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) { 774a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 775a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipV); 776a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 777a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 778a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 779a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 780a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 781a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 782a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxRot90); 783a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 784a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 785a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 786f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis } 787f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 7885c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner sp<GraphicBuffer> buf = (mCurrentTextureImage == NULL) ? 7895c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner NULL : mCurrentTextureImage->graphicBuffer(); 790e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 791e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (buf == NULL) { 792d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGD("computeCurrentTransformMatrixLocked: mCurrentTextureImage is NULL"); 793e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian } 794e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 795dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis float mtxBeforeFlipV[16]; 796dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis if (!isEglImageCroppable(mCurrentCrop)) { 797dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis Rect cropRect = mCurrentCrop; 798dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis float tx = 0.0f, ty = 0.0f, sx = 1.0f, sy = 1.0f; 799dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis float bufferWidth = buf->getWidth(); 800dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis float bufferHeight = buf->getHeight(); 801dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis if (!cropRect.isEmpty()) { 802dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis float shrinkAmount = 0.0f; 803dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis if (mFilteringEnabled) { 804dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // In order to prevent bilinear sampling beyond the edge of the 805dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // crop rectangle we may need to shrink it by 2 texels in each 806dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // dimension. Normally this would just need to take 1/2 a texel 807dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // off each end, but because the chroma channels of YUV420 images 808dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // are subsampled we may need to shrink the crop region by a whole 809dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // texel on each side. 810dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis switch (buf->getPixelFormat()) { 811dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis case PIXEL_FORMAT_RGBA_8888: 812dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis case PIXEL_FORMAT_RGBX_8888: 813dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis case PIXEL_FORMAT_RGB_888: 814dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis case PIXEL_FORMAT_RGB_565: 815dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis case PIXEL_FORMAT_BGRA_8888: 816dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // We know there's no subsampling of any channels, so we 817dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // only need to shrink by a half a pixel. 818dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis shrinkAmount = 0.5; 819dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis break; 820dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 821dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis default: 822dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // If we don't recognize the format, we must assume the 823dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // worst case (that we care about), which is YUV420. 824dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis shrinkAmount = 1.0; 825dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis break; 826dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis } 8275c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 8285c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis 829dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // Only shrink the dimensions that are not the size of the buffer. 830dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis if (cropRect.width() < bufferWidth) { 831dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis tx = (float(cropRect.left) + shrinkAmount) / bufferWidth; 832dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis sx = (float(cropRect.width()) - (2.0f * shrinkAmount)) / 833dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bufferWidth; 834dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis } 835dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis if (cropRect.height() < bufferHeight) { 836dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis ty = (float(bufferHeight - cropRect.bottom) + shrinkAmount) / 837dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bufferHeight; 838dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis sy = (float(cropRect.height()) - (2.0f * shrinkAmount)) / 839dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bufferHeight; 840dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis } 8415c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 842dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis float crop[16] = { 843dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis sx, 0, 0, 0, 844dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 0, sy, 0, 0, 845dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 0, 0, 1, 0, 846dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis tx, ty, 0, 1, 847dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis }; 848dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 849dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis mtxMul(mtxBeforeFlipV, crop, xform); 850dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis } else { 851dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis for (int i = 0; i < 16; i++) { 852dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis mtxBeforeFlipV[i] = xform[i]; 8535c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 854a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 855a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis 856a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // SurfaceFlinger expects the top of its window textures to be at a Y 8572adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden // coordinate of 0, so GLConsumer must behave the same way. We don't 858a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // want to expose this to applications, however, so we must add an 859a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // additional vertical flip to the transform after all the other transforms. 860736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis mtxMul(mCurrentTransformMatrix, mtxFlipV, mtxBeforeFlipV); 861f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 862f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 8632adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddennsecs_t GLConsumer::getTimestamp() { 864d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("getTimestamp"); 8651d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala Mutex::Autolock lock(mMutex); 8661d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala return mCurrentTimestamp; 8671d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala} 8681d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala 869d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stozauint64_t GLConsumer::getFrameNumber() { 870d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("getFrameNumber"); 871d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala Mutex::Autolock lock(mMutex); 872d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala return mCurrentFrameNumber; 873d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala} 874d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala 8752adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddensp<GraphicBuffer> GLConsumer::getCurrentBuffer() const { 8767a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 8775c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner return (mCurrentTextureImage == NULL) ? 8785c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner NULL : mCurrentTextureImage->graphicBuffer(); 8797a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 8807a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 8812adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenRect GLConsumer::getCurrentCrop() const { 8827a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 883016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 884016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam Rect outCrop = mCurrentCrop; 885016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { 886d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza uint32_t newWidth = static_cast<uint32_t>(mCurrentCrop.width()); 887d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza uint32_t newHeight = static_cast<uint32_t>(mCurrentCrop.height()); 888016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 889016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (newWidth * mDefaultHeight > newHeight * mDefaultWidth) { 890016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam newWidth = newHeight * mDefaultWidth / mDefaultHeight; 891d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("too wide: newWidth = %d", newWidth); 892016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } else if (newWidth * mDefaultHeight < newHeight * mDefaultWidth) { 893016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam newHeight = newWidth * mDefaultHeight / mDefaultWidth; 894d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("too tall: newHeight = %d", newHeight); 895016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 896016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 897d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza uint32_t currentWidth = static_cast<uint32_t>(mCurrentCrop.width()); 898d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza uint32_t currentHeight = static_cast<uint32_t>(mCurrentCrop.height()); 899d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza 900016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The crop is too wide 901d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza if (newWidth < currentWidth) { 902d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza uint32_t dw = (newWidth - currentWidth) / 2; 903016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.left -=dw; 904016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.right += dw; 905016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The crop is too tall 906d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza } else if (newHeight < currentHeight) { 907d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza uint32_t dh = (newHeight - currentHeight) / 2; 908016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.top -= dh; 909016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.bottom += dh; 910016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 911016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 912d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("getCurrentCrop final crop [%d,%d,%d,%d]", 913016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.left, outCrop.top, 914016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.right,outCrop.bottom); 915016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 916016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 917016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam return outCrop; 9187a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 9197a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 9202adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenuint32_t GLConsumer::getCurrentTransform() const { 9217a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 9227a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTransform; 9237a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 9247a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 9252adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenuint32_t GLConsumer::getCurrentScalingMode() const { 9267734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian Mutex::Autolock lock(mMutex); 9277734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian return mCurrentScalingMode; 9287734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian} 9297734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian 9302adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddensp<Fence> GLConsumer::getCurrentFence() const { 931dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall Mutex::Autolock lock(mMutex); 932dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall return mCurrentFence; 933dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall} 934dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 9352adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::doGLFenceWait() const { 93661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis Mutex::Autolock lock(mMutex); 9373941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis return doGLFenceWaitLocked(); 9383941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis} 9393941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis 9402adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::doGLFenceWaitLocked() const { 94161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 94261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 94361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 94461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 94561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (mEglDisplay != dpy || mEglDisplay == EGL_NO_DISPLAY) { 946d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("doGLFenceWait: invalid current EGLDisplay"); 94761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return INVALID_OPERATION; 94861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 94961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 95061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (mEglContext != ctx || mEglContext == EGL_NO_CONTEXT) { 951d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("doGLFenceWait: invalid current EGLContext"); 95261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return INVALID_OPERATION; 95361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 95461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 9551df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis if (mCurrentFence->isValid()) { 956ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian if (SyncFeatures::getInstance().useWaitSync()) { 95761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // Create an EGLSyncKHR from the current fence. 95861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis int fenceFd = mCurrentFence->dup(); 95961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (fenceFd == -1) { 960d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("doGLFenceWait: error dup'ing fence fd: %d", errno); 96161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return -errno; 96261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 96361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLint attribs[] = { 96461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd, 96561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_NONE 96661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis }; 96761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLSyncKHR sync = eglCreateSyncKHR(dpy, 96861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_SYNC_NATIVE_FENCE_ANDROID, attribs); 96961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (sync == EGL_NO_SYNC_KHR) { 97061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis close(fenceFd); 971d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("doGLFenceWait: error creating EGL fence: %#x", 97261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglGetError()); 97361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return UNKNOWN_ERROR; 97461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 97561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 97661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // XXX: The spec draft is inconsistent as to whether this should 97761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // return an EGLint or void. Ignore the return value for now, as 97861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // it's not strictly needed. 9792bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian eglWaitSyncKHR(dpy, sync, 0); 98061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLint eglErr = eglGetError(); 98161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglDestroySyncKHR(dpy, sync); 98261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (eglErr != EGL_SUCCESS) { 983d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("doGLFenceWait: error waiting for EGL fence: %#x", 98461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglErr); 98561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return UNKNOWN_ERROR; 98661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 98761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } else { 988ea74d3b78d607cde17790a7bb83e6f68ffd34cfdMathias Agopian status_t err = mCurrentFence->waitForever( 9892adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden "GLConsumer::doGLFenceWaitLocked"); 99061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (err != NO_ERROR) { 991d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("doGLFenceWait: error waiting for fence: %d", err); 99261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return err; 99361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 99461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 99561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 99661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 99761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return NO_ERROR; 99861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis} 99961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 10002adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::freeBufferLocked(int slotIndex) { 1001d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("freeBufferLocked: slotIndex=%d", slotIndex); 10029abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (slotIndex == mCurrentTexture) { 10039abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; 10049abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 10055c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglSlots[slotIndex].mEglImage.clear(); 10069fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase::freeBufferLocked(slotIndex); 1007fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 1008fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 10092adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::abandonLocked() { 1010d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("abandonLocked"); 10115c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTextureImage.clear(); 10129fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase::abandonLocked(); 10137b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis} 10147b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 10152adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::setName(const String8& name) { 1016eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 1017fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis mName = name; 1018db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian mConsumer->setConsumerName(name); 1019b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 1020b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 1021d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stozastatus_t GLConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) { 1022b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 1023db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setDefaultBufferFormat(defaultFormat); 1024b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 1025b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 10262adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setConsumerUsageBits(uint32_t usage) { 1027b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 102885b217668d6840c8e6a109adfb99461313676f8dEino-Ville Talvala usage |= DEFAULT_USAGE_FLAGS; 1029db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setConsumerUsageBits(usage); 1030b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 1031b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 10322adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setTransformHint(uint32_t hint) { 1033b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 1034db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setTransformHint(hint); 1035b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 1036b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 103774d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid GLConsumer::dumpLocked(String8& result, const char* prefix) const 103868c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian{ 103974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 10409fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis "%smTexName=%d mCurrentTexture=%d\n" 10419fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis "%smCurrentCrop=[%d,%d,%d,%d] mCurrentTransform=%#x\n", 10429fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis prefix, mTexName, mCurrentTexture, prefix, mCurrentCrop.left, 10439fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom, 10449fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentTransform); 104568c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 104674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian ConsumerBase::dumpLocked(result, prefix); 104768c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian} 104868c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 1049f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]) { 1050f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3]; 1051f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3]; 1052f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3]; 1053f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3]; 1054f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1055f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7]; 1056f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7]; 1057f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7]; 1058f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7]; 1059f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1060f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11]; 1061f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11]; 1062f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11]; 1063f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11]; 1064f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1065f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15]; 1066f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15]; 1067f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15]; 1068f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15]; 1069f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 1070f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 10715c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric PennerGLConsumer::EglImage::EglImage(sp<GraphicBuffer> graphicBuffer) : 10725c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mGraphicBuffer(graphicBuffer), 10735c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglImage(EGL_NO_IMAGE_KHR), 10745c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglDisplay(EGL_NO_DISPLAY) { 10755c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner} 10765c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 10775c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric PennerGLConsumer::EglImage::~EglImage() { 10785c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (mEglImage != EGL_NO_IMAGE_KHR) { 10795c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (!eglDestroyImageKHR(mEglDisplay, mEglImage)) { 10805c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner ALOGE("~EglImage: eglDestroyImageKHR failed"); 10815c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 108278be65e7bf6898c6afa55c9016f331ab1aa2503aMichael Lentine eglTerminate(mEglDisplay); 10835c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 10845c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner} 10855c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 10865c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Pennerstatus_t GLConsumer::EglImage::createIfNeeded(EGLDisplay eglDisplay, 10872d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner const Rect& cropRect, 10882d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner bool forceCreation) { 10895c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // If there's an image and it's no longer valid, destroy it. 10905c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner bool haveImage = mEglImage != EGL_NO_IMAGE_KHR; 10915c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner bool displayInvalid = mEglDisplay != eglDisplay; 10925c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner bool cropInvalid = hasEglAndroidImageCrop() && mCropRect != cropRect; 10932d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner if (haveImage && (displayInvalid || cropInvalid || forceCreation)) { 10945c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (!eglDestroyImageKHR(mEglDisplay, mEglImage)) { 10955c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner ALOGE("createIfNeeded: eglDestroyImageKHR failed"); 10965c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 109778be65e7bf6898c6afa55c9016f331ab1aa2503aMichael Lentine eglTerminate(mEglDisplay); 10985c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglImage = EGL_NO_IMAGE_KHR; 10995c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglDisplay = EGL_NO_DISPLAY; 11005c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 11015c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 11025c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // If there's no image, create one. 11035c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (mEglImage == EGL_NO_IMAGE_KHR) { 11045c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglDisplay = eglDisplay; 11055c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCropRect = cropRect; 11065c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglImage = createImage(mEglDisplay, mGraphicBuffer, mCropRect); 11075c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 11085c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 11095c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // Fail if we can't create a valid image. 11105c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (mEglImage == EGL_NO_IMAGE_KHR) { 11115c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglDisplay = EGL_NO_DISPLAY; 11125c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCropRect.makeInvalid(); 11135c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner const sp<GraphicBuffer>& buffer = mGraphicBuffer; 11145c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner ALOGE("Failed to create image. size=%ux%u st=%u usage=0x%x fmt=%d", 11155c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner buffer->getWidth(), buffer->getHeight(), buffer->getStride(), 11165c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner buffer->getUsage(), buffer->getPixelFormat()); 11175c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner return UNKNOWN_ERROR; 11185c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 11195c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 11205c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner return OK; 11215c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner} 11225c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 11235c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Pennervoid GLConsumer::EglImage::bindToTextureTarget(uint32_t texTarget) { 1124d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza glEGLImageTargetTexture2DOES(texTarget, 1125d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza static_cast<GLeglImageOES>(mEglImage)); 11265c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner} 11275c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 11285c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric PennerEGLImageKHR GLConsumer::EglImage::createImage(EGLDisplay dpy, 11295c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner const sp<GraphicBuffer>& graphicBuffer, const Rect& crop) { 1130d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza EGLClientBuffer cbuf = 1131d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza static_cast<EGLClientBuffer>(graphicBuffer->getNativeBuffer()); 11325c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGLint attrs[] = { 11335c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 11345c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGL_IMAGE_CROP_LEFT_ANDROID, crop.left, 11355c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGL_IMAGE_CROP_TOP_ANDROID, crop.top, 11365c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGL_IMAGE_CROP_RIGHT_ANDROID, crop.right, 11375c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGL_IMAGE_CROP_BOTTOM_ANDROID, crop.bottom, 11385c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGL_NONE, 11395c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner }; 11405c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (!crop.isValid()) { 11415c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // No crop rect to set, so terminate the attrib array before the crop. 11425c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner attrs[2] = EGL_NONE; 11435c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } else if (!isEglImageCroppable(crop)) { 11445c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // The crop rect is not at the origin, so we can't set the crop on the 11455c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // EGLImage because that's not allowed by the EGL_ANDROID_image_crop 11465c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // extension. In the future we can add a layered extension that 11475c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // removes this restriction if there is hardware that can support it. 11485c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner attrs[2] = EGL_NONE; 11495c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 115078be65e7bf6898c6afa55c9016f331ab1aa2503aMichael Lentine eglInitialize(dpy, 0, 0); 11515c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, 11525c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs); 11535c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (image == EGL_NO_IMAGE_KHR) { 11545c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGLint error = eglGetError(); 11555c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner ALOGE("error creating EGLImage: %#x", error); 115678be65e7bf6898c6afa55c9016f331ab1aa2503aMichael Lentine eglTerminate(dpy); 11575c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 11585c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner return image; 11595c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner} 11605c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 11618ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis}; // namespace android 1162