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 32dd26416fe135f93ef2c8570738f8e1ca5e2ca3a3Dan Stoza#include <gui/BufferItem.h> 33ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian#include <gui/GLConsumer.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" 46aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner#define PROT_CONTENT_EXT_STR "EGL_EXT_protected_content" 47aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner#define EGL_PROTECTED_CONTENT_EXT 0x32C0 48dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 4997eba8904c2f221c42a9473407223a4c3a213f75Andy McFaddennamespace android { 5097eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden 512adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden// Macros for including the GLConsumer name in log messages 52d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza#define GLC_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__) 53d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza#define GLC_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__) 54d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza//#define GLC_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__) 55d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza#define GLC_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__) 56d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza#define GLC_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__) 5729b5762efc359022168e5099c1d17925444d3147Mathias Agopian 58ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopianstatic const struct { 59d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza uint32_t width, height; 60ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian char const* bits; 6145263e2475ac6a885dbd78eff7d4e44f374e5237Mathias Agopian} kDebugData = { 15, 12, 62d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "_______________" 63d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "_______________" 64d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "_____XX_XX_____" 65d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "__X_X_____X_X__" 66d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "__X_XXXXXXX_X__" 67d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "__XXXXXXXXXXX__" 68d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "___XX_XXX_XX___" 69d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "____XXXXXXX____" 70d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "_____X___X_____" 71d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "____X_____X____" 72d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "_______________" 73d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza "_______________" 7445263e2475ac6a885dbd78eff7d4e44f374e5237Mathias Agopian}; 75ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 76f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis// Transform matrices 77f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxIdentity[16] = { 78f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 0, 79f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 80f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 81f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 0, 1, 82f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 83f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxFlipH[16] = { 84f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis -1, 0, 0, 0, 85f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 86f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 87f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 1, 88f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 89f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxFlipV[16] = { 90f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 0, 91f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, -1, 0, 0, 92f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 93f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 1, 94f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 95f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic float mtxRot90[16] = { 96f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 1, 0, 0, 97f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis -1, 0, 0, 0, 98f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 0, 0, 1, 0, 99f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1, 0, 0, 1, 100f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis}; 101f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 102f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]); 103f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1049870c9b66cc73ee31aabba23aa06deaf673ee5efMathias AgopianMutex GLConsumer::sStaticInitLock; 1059870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopiansp<GraphicBuffer> GLConsumer::sReleasedTexImageBuffer; 106fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis 107dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennisstatic bool hasEglAndroidImageCropImpl() { 108dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 109dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis const char* exts = eglQueryStringImplementationANDROID(dpy, EGL_EXTENSIONS); 110dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis size_t cropExtLen = strlen(CROP_EXT_STR); 111dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis size_t extsLen = strlen(exts); 112dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bool equal = !strcmp(CROP_EXT_STR, exts); 113dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bool atStart = !strncmp(CROP_EXT_STR " ", exts, cropExtLen+1); 114dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bool atEnd = (cropExtLen+1) < extsLen && 115dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis !strcmp(" " CROP_EXT_STR, exts + extsLen - (cropExtLen+1)); 116dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis bool inMiddle = strstr(exts, " " CROP_EXT_STR " "); 117dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis return equal || atStart || atEnd || inMiddle; 118dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis} 119dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 120dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennisstatic bool hasEglAndroidImageCrop() { 121dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // Only compute whether the extension is present once the first time this 122dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis // function is called. 123dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis static bool hasIt = hasEglAndroidImageCropImpl(); 124dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis return hasIt; 125dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis} 126dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 127aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donnerstatic bool hasEglProtectedContentImpl() { 128aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 129aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner const char* exts = eglQueryString(dpy, EGL_EXTENSIONS); 130aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner size_t cropExtLen = strlen(PROT_CONTENT_EXT_STR); 131aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner size_t extsLen = strlen(exts); 132aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner bool equal = !strcmp(PROT_CONTENT_EXT_STR, exts); 133aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner bool atStart = !strncmp(PROT_CONTENT_EXT_STR " ", exts, cropExtLen+1); 134aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner bool atEnd = (cropExtLen+1) < extsLen && 135aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner !strcmp(" " PROT_CONTENT_EXT_STR, exts + extsLen - (cropExtLen+1)); 136aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner bool inMiddle = strstr(exts, " " PROT_CONTENT_EXT_STR " "); 1374df76b2f5f7e8be128b5ec7a2d8d03845effaea0Craig Donner return equal || atStart || atEnd || inMiddle; 138aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner} 139aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner 140aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donnerstatic bool hasEglProtectedContent() { 141aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner // Only compute whether the extension is present once the first time this 142aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner // function is called. 143aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner static bool hasIt = hasEglProtectedContentImpl(); 144aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner return hasIt; 145aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner} 146aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner 147dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennisstatic bool isEglImageCroppable(const Rect& crop) { 148dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis return hasEglAndroidImageCrop() && (crop.left == 0 && crop.top == 0); 149dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis} 150dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 1513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias AgopianGLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex, 1523f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian uint32_t texTarget, bool useFenceSync, bool isControlledByApp) : 153595264f1af12e25dce57d7c5b1d52ed86ac0d0c9Mathias Agopian ConsumerBase(bq, isControlledByApp), 15460d6922a011fe18c111b8d30fb6ef1f655b6b15ePablo Ceballos mCurrentCrop(Rect::EMPTY_RECT), 1551d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTransform(0), 156e692ab9a6be63193c5b52a6562d85d06c40463b8Mathias Agopian mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 1571df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis mCurrentFence(Fence::NO_FENCE), 1581d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala mCurrentTimestamp(0), 159bb09b436fa119ad8b97f1bf5c04cc5aa10b5f1f0Courtney Goeltzenleuchter mCurrentDataSpace(HAL_DATASPACE_UNKNOWN), 160d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala mCurrentFrameNumber(0), 161e692ab9a6be63193c5b52a6562d85d06c40463b8Mathias Agopian mDefaultWidth(1), 162e692ab9a6be63193c5b52a6562d85d06c40463b8Mathias Agopian mDefaultHeight(1), 1635c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis mFilteringEnabled(true), 164b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian mTexName(tex), 16586edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis mUseFenceSync(useFenceSync), 166eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam mTexTarget(texTarget), 167ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglDisplay(EGL_NO_DISPLAY), 168ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis mEglContext(EGL_NO_CONTEXT), 16974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), 17074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached(true) 1716b091c53000c843211c218ce40287a7edca9bc63Daniel Lam{ 172d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("GLConsumer"); 173b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 174fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis memcpy(mCurrentTransformMatrix, mtxIdentity, 175fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis sizeof(mCurrentTransformMatrix)); 176fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 177db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS); 1788ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 1798ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 180ab57491de3a89a2d454d3060d36adef71741a7aeDan StozaGLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t texTarget, 181ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza bool useFenceSync, bool isControlledByApp) : 182ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza ConsumerBase(bq, isControlledByApp), 18360d6922a011fe18c111b8d30fb6ef1f655b6b15ePablo Ceballos mCurrentCrop(Rect::EMPTY_RECT), 184ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mCurrentTransform(0), 185ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 186ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mCurrentFence(Fence::NO_FENCE), 187ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mCurrentTimestamp(0), 188bb09b436fa119ad8b97f1bf5c04cc5aa10b5f1f0Courtney Goeltzenleuchter mCurrentDataSpace(HAL_DATASPACE_UNKNOWN), 189ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mCurrentFrameNumber(0), 190ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mDefaultWidth(1), 191ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mDefaultHeight(1), 192ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mFilteringEnabled(true), 193d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza mTexName(0), 194ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mUseFenceSync(useFenceSync), 195ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mTexTarget(texTarget), 196ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mEglDisplay(EGL_NO_DISPLAY), 197ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mEglContext(EGL_NO_CONTEXT), 198ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT), 199ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mAttached(false) 200ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza{ 201d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("GLConsumer"); 202ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza 203ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza memcpy(mCurrentTransformMatrix, mtxIdentity, 204ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza sizeof(mCurrentTransformMatrix)); 205ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza 206ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS); 207ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza} 208ab57491de3a89a2d454d3060d36adef71741a7aeDan Stoza 2092adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setDefaultBufferSize(uint32_t w, uint32_t h) 210a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian{ 211b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 21265d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos if (mAbandoned) { 21365d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos GLC_LOGE("setDefaultBufferSize: GLConsumer is abandoned!"); 21465d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos return NO_INIT; 21565d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos } 216016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam mDefaultWidth = w; 217016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam mDefaultHeight = h; 218db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setDefaultBufferSize(w, h); 219a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian} 220a5c75c01620179ce00812354778a29a80d76e71fMathias Agopian 2212adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::updateTexImage() { 222bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ATRACE_CALL(); 223d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("updateTexImage"); 224bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden Mutex::Autolock lock(mMutex); 225bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 226bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mAbandoned) { 227d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("updateTexImage: GLConsumer is abandoned!"); 228bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return NO_INIT; 229bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 230bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 231bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Make sure the EGL state is the same as in previous calls. 232bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden status_t err = checkAndUpdateEglStateLocked(); 233bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 234bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 235bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 236bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 237dd26416fe135f93ef2c8570738f8e1ca5e2ca3a3Dan Stoza BufferItem item; 238bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 239bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Acquire the next buffer. 240bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // In asynchronous mode the list is guaranteed to be one buffer 241bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // deep, while in synchronous mode we use the oldest buffer. 2421585c4d9fbbba3ba70ae625923b85cd02cb8a0fdAndy McFadden err = acquireBufferLocked(&item, 0); 243bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 244bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 245bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We always bind the texture even if we don't update its contents. 246d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("updateTexImage: no buffers were available"); 247bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 248bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = NO_ERROR; 249bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } else { 250d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("updateTexImage: acquire failed: %s (%d)", 251bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden strerror(-err), err); 252bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 253bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 254bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 255bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 256bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Release the previous buffer. 257ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian err = updateAndReleaseLocked(item); 258bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 259bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We always bind the texture. 260bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 261bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 262bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 263bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 26497eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // Bind the new buffer to the GL texture, and wait until it's ready. 26597eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden return bindTextureImageLocked(); 2662c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian} 2672c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 268ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 269ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopianstatus_t GLConsumer::releaseTexImage() { 270ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian ATRACE_CALL(); 271d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("releaseTexImage"); 272ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian Mutex::Autolock lock(mMutex); 273ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 274ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (mAbandoned) { 275d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("releaseTexImage: GLConsumer is abandoned!"); 276ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return NO_INIT; 277ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 278ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 279ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian // Make sure the EGL state is the same as in previous calls. 28045155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian status_t err = NO_ERROR; 28145155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian 28245155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mAttached) { 28345155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian err = checkAndUpdateEglStateLocked(true); 28445155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (err != NO_ERROR) { 28545155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian return err; 28645155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 28745155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } else { 28845155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // if we're detached, no need to validate EGL's state -- we won't use it. 289ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 290ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 291ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian // Update the GLConsumer state. 292ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian int buf = mCurrentTexture; 293ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (buf != BufferQueue::INVALID_BUFFER_SLOT) { 294ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 295d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("releaseTexImage: (slot=%d, mAttached=%d)", buf, mAttached); 296ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 29745155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mAttached) { 29845155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // Do whatever sync ops we need to do before releasing the slot. 29945155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian err = syncForReleaseLocked(mEglDisplay); 30045155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (err != NO_ERROR) { 301d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("syncForReleaseLocked failed (slot=%d), err=%d", buf, err); 30245155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian return err; 30345155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 30445155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } else { 30545155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // if we're detached, we just use the fence that was created in detachFromContext() 30645155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // so... basically, nothing more to do here. 307ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 308ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 30945155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian err = releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, mEglDisplay, EGL_NO_SYNC_KHR); 310ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian if (err < NO_ERROR) { 311d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("releaseTexImage: failed to release buffer: %s (%d)", 312ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian strerror(-err), err); 313ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return err; 314ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 315ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 3165c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (mReleasedTexImage == NULL) { 3175c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mReleasedTexImage = new EglImage(getDebugTexImageBuffer()); 3185c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 3195c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 320ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; 3215c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTextureImage = mReleasedTexImage; 322ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentCrop.makeInvalid(); 323ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentTransform = 0; 324ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentTimestamp = 0; 325bb09b436fa119ad8b97f1bf5c04cc5aa10b5f1f0Courtney Goeltzenleuchter mCurrentDataSpace = HAL_DATASPACE_UNKNOWN; 326ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian mCurrentFence = Fence::NO_FENCE; 3273d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson mCurrentFenceTime = FenceTime::NO_FENCE; 328ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 32945155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mAttached) { 3305c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // This binds a dummy buffer (mReleasedTexImage). 331d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza status_t result = bindTextureImageLocked(); 332d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza if (result != NO_ERROR) { 333d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza return result; 3345c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 33545155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } else { 33645155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // detached, don't touch the texture (and we may not even have an 33745155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // EGLDisplay here. 33845155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 339ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian } 340ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 341ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian return NO_ERROR; 342ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian} 343ad678e18b66f495efa78dc3b9ab99b579945c9e2Mathias Agopian 3449870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopiansp<GraphicBuffer> GLConsumer::getDebugTexImageBuffer() { 3459870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian Mutex::Autolock _l(sStaticInitLock); 3469870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian if (CC_UNLIKELY(sReleasedTexImageBuffer == NULL)) { 3479870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian // The first time, create the debug texture in case the application 3489870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian // continues to use it. 3499870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian sp<GraphicBuffer> buffer = new GraphicBuffer( 3509870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian kDebugData.width, kDebugData.height, PIXEL_FORMAT_RGBA_8888, 351d4079aff759713e7c7dd14cecb585a7290e80772Dan Stoza GraphicBuffer::USAGE_SW_WRITE_RARELY, 352d4079aff759713e7c7dd14cecb585a7290e80772Dan Stoza "[GLConsumer debug texture]"); 3539870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian uint32_t* bits; 3549870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&bits)); 355d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza uint32_t stride = buffer->getStride(); 356d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza uint32_t height = buffer->getHeight(); 357d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza memset(bits, 0, stride * height * 4); 358d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza for (uint32_t y = 0; y < kDebugData.height; y++) { 359d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza for (uint32_t x = 0; x < kDebugData.width; x++) { 360d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza bits[x] = (kDebugData.bits[y + kDebugData.width + x] == 'X') ? 361d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza 0xFF000000 : 0xFFFFFFFF; 3629870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian } 363d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza bits += stride; 3649870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian } 3659870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian buffer->unlock(); 3669870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian sReleasedTexImageBuffer = buffer; 3679870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian } 3689870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian return sReleasedTexImageBuffer; 3699870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian} 3709870c9b66cc73ee31aabba23aa06deaf673ee5efMathias Agopian 371dd26416fe135f93ef2c8570738f8e1ca5e2ca3a3Dan Stozastatus_t GLConsumer::acquireBufferLocked(BufferItem *item, 372a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza nsecs_t presentWhen, uint64_t maxFrameNumber) { 373a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen, 374a4650a50a0b35e9e4342d6600b6eb24fd94bb8e5Dan Stoza maxFrameNumber); 3759fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis if (err != NO_ERROR) { 3769fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return err; 3779fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 3789fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 3795c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // If item->mGraphicBuffer is not null, this buffer has not been acquired 3805c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // before, so any prior EglImage created is using a stale buffer. This 3815c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // replaces any old EglImage with a new one (using the new buffer). 3825c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (item->mGraphicBuffer != NULL) { 38347650f4f66a49e1815ad08ca4fb12a661d133abcPablo Ceballos int slot = item->mSlot; 3845c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglSlots[slot].mEglImage = new EglImage(item->mGraphicBuffer); 3859fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis } 3869fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 3879fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return NO_ERROR; 3889fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis} 3899fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 390c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnarstatus_t GLConsumer::releaseBufferLocked(int buf, 391c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar sp<GraphicBuffer> graphicBuffer, 392c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar EGLDisplay display, EGLSyncKHR eglFence) { 393c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // release the buffer if it hasn't already been discarded by the 394c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // BufferQueue. This can happen, for example, when the producer of this 395c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // buffer has reallocated the original buffer slot after this buffer 396c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar // was acquired. 397c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = ConsumerBase::releaseBufferLocked( 398c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar buf, graphicBuffer, display, eglFence); 399d1b330de416adff0d178a5cb7271419d9ed7a89aJamie Gennis mEglSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 4009fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis return err; 4019fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis} 4029fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis 4033ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stozastatus_t GLConsumer::updateAndReleaseLocked(const BufferItem& item, 4043ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza PendingRelease* pendingRelease) 405bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden{ 4069abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam status_t err = NO_ERROR; 4079abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam 40847650f4f66a49e1815ad08ca4fb12a661d133abcPablo Ceballos int slot = item.mSlot; 40987a678478005026d950bedec49ee80b693777b95Andy McFadden 41074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (!mAttached) { 411d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("updateAndRelease: GLConsumer is not attached to an OpenGL " 41274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "ES context"); 41347650f4f66a49e1815ad08ca4fb12a661d133abcPablo Ceballos releaseBufferLocked(slot, mSlots[slot].mGraphicBuffer, 41487a678478005026d950bedec49ee80b693777b95Andy McFadden mEglDisplay, EGL_NO_SYNC_KHR); 41574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 41674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 41774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 418bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Confirm state. 419bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden err = checkAndUpdateEglStateLocked(); 420bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (err != NO_ERROR) { 42147650f4f66a49e1815ad08ca4fb12a661d133abcPablo Ceballos releaseBufferLocked(slot, mSlots[slot].mGraphicBuffer, 42287a678478005026d950bedec49ee80b693777b95Andy McFadden mEglDisplay, EGL_NO_SYNC_KHR); 423bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 424ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 425ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 4265c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // Ensure we have a valid EglImageKHR for the slot, creating an EglImage 4275c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // if nessessary, for the gralloc buffer currently in the slot in 4285c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // ConsumerBase. 429bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // We may have to do this even when item.mGraphicBuffer == NULL (which 4305c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // means the buffer was previously acquired). 43147650f4f66a49e1815ad08ca4fb12a661d133abcPablo Ceballos err = mEglSlots[slot].mEglImage->createIfNeeded(mEglDisplay, item.mCrop); 4325c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (err != NO_ERROR) { 433d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGW("updateAndRelease: unable to createImage on display=%p slot=%d", 43447650f4f66a49e1815ad08ca4fb12a661d133abcPablo Ceballos mEglDisplay, slot); 43547650f4f66a49e1815ad08ca4fb12a661d133abcPablo Ceballos releaseBufferLocked(slot, mSlots[slot].mGraphicBuffer, 4365c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglDisplay, EGL_NO_SYNC_KHR); 4375c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner return UNKNOWN_ERROR; 438ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis } 439ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 440bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // Do whatever sync ops we need to do before releasing the old slot. 441ff95aabbcc6e8606acbd7933c90eeb9b8b382a21Pablo Ceballos if (slot != mCurrentTexture) { 44233fcc2ecf707bfa15360d6d3ec95c778423d3032Pablo Ceballos err = syncForReleaseLocked(mEglDisplay); 44333fcc2ecf707bfa15360d6d3ec95c778423d3032Pablo Ceballos if (err != NO_ERROR) { 44433fcc2ecf707bfa15360d6d3ec95c778423d3032Pablo Ceballos // Release the buffer we just acquired. It's not safe to 44533fcc2ecf707bfa15360d6d3ec95c778423d3032Pablo Ceballos // release the old buffer, so instead we just drop the new frame. 44633fcc2ecf707bfa15360d6d3ec95c778423d3032Pablo Ceballos // As we are still under lock since acquireBuffer, it is safe to 44733fcc2ecf707bfa15360d6d3ec95c778423d3032Pablo Ceballos // release by slot. 44833fcc2ecf707bfa15360d6d3ec95c778423d3032Pablo Ceballos releaseBufferLocked(slot, mSlots[slot].mGraphicBuffer, 44933fcc2ecf707bfa15360d6d3ec95c778423d3032Pablo Ceballos mEglDisplay, EGL_NO_SYNC_KHR); 45033fcc2ecf707bfa15360d6d3ec95c778423d3032Pablo Ceballos return err; 45133fcc2ecf707bfa15360d6d3ec95c778423d3032Pablo Ceballos } 452bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 453ce561372186c7549a8a5fe996ac5965cda087007Jamie Gennis 454d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", 4555c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTexture, mCurrentTextureImage != NULL ? 4565c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTextureImage->graphicBufferHandle() : 0, 45747650f4f66a49e1815ad08ca4fb12a661d133abcPablo Ceballos slot, mSlots[slot].mGraphicBuffer->handle); 458eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam 459ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // Hang onto the pointer so that it isn't freed in the call to 4603559fbf93801e2c0d9d8fb246fb9b867a361b464Pablo Ceballos // releaseBufferLocked() if we're in shared buffer mode and both buffers are 461ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos // the same. 462ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos sp<EglImage> nextTextureImage = mEglSlots[slot].mEglImage; 463ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos 464bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden // release old buffer 465bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 4663ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza if (pendingRelease == nullptr) { 4673ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza status_t status = releaseBufferLocked( 4683ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza mCurrentTexture, mCurrentTextureImage->graphicBuffer(), 4693ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza mEglDisplay, mEglSlots[mCurrentTexture].mEglFence); 4703ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza if (status < NO_ERROR) { 4713ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza GLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)", 4723ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza strerror(-status), status); 4733ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza err = status; 4743ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza // keep going, with error raised [?] 4753ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza } 4763ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza } else { 4773ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza pendingRelease->currentTexture = mCurrentTexture; 4783ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza pendingRelease->graphicBuffer = 4793ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza mCurrentTextureImage->graphicBuffer(); 4803ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza pendingRelease->display = mEglDisplay; 4813ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza pendingRelease->fence = mEglSlots[mCurrentTexture].mEglFence; 4823ce460440b0ab0b6d6407c9d8735b19f6e3b8408Dan Stoza pendingRelease->isPending = true; 4832c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian } 484bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 4852c8207e9627fe6c7a90e31fae8d71ae49df56845Mathias Agopian 4862adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden // Update the GLConsumer state. 48747650f4f66a49e1815ad08ca4fb12a661d133abcPablo Ceballos mCurrentTexture = slot; 488ccdfd60d79a8b7f1ed6401d0f2e8e29166a10584Pablo Ceballos mCurrentTextureImage = nextTextureImage; 489bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentCrop = item.mCrop; 490bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTransform = item.mTransform; 491bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentScalingMode = item.mScalingMode; 492bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentTimestamp = item.mTimestamp; 493bb09b436fa119ad8b97f1bf5c04cc5aa10b5f1f0Courtney Goeltzenleuchter mCurrentDataSpace = item.mDataSpace; 494bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mCurrentFence = item.mFence; 4953d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson mCurrentFenceTime = item.mFenceTime; 496d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala mCurrentFrameNumber = item.mFrameNumber; 497bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 498bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden computeCurrentTransformMatrixLocked(); 499bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 500bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return err; 501bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 502bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 5032adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::bindTextureImageLocked() { 504bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden if (mEglDisplay == EGL_NO_DISPLAY) { 505bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden ALOGE("bindTextureImage: invalid display"); 506bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 507bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 508bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 509d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLenum error; 510bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden while ((error = glGetError()) != GL_NO_ERROR) { 511d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGW("bindTextureImage: clearing GL error: %#04x", error); 512bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 513bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 514bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden glBindTexture(mTexTarget, mTexName); 5155c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && 5165c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTextureImage == NULL) { 517d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("bindTextureImage: no currently-bound texture"); 5185c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner return NO_INIT; 5195c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 5200eb8851e8cc35f443646000220e42dba3adfab8bJamie Gennis 5215c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner status_t err = mCurrentTextureImage->createIfNeeded(mEglDisplay, 5222d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner mCurrentCrop); 5235c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (err != NO_ERROR) { 524d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGW("bindTextureImage: can't create image on display=%p slot=%d", 5255c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglDisplay, mCurrentTexture); 5265c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner return UNKNOWN_ERROR; 5275c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 5285c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTextureImage->bindToTextureTarget(mTexTarget); 5295c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 5302d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner // In the rare case that the display is terminated and then initialized 5312d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner // again, we can't detect that the display changed (it didn't), but the 5322d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner // image is invalid. In this case, repeat the exact same steps while 5332d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner // forcing the creation of a new image. 5342d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner if ((error = glGetError()) != GL_NO_ERROR) { 5352d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner glBindTexture(mTexTarget, mTexName); 536d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza status_t result = mCurrentTextureImage->createIfNeeded(mEglDisplay, 537d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza mCurrentCrop, 538d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza true); 539d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza if (result != NO_ERROR) { 540d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGW("bindTextureImage: can't create image on display=%p slot=%d", 5412d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner mEglDisplay, mCurrentTexture); 5422d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner return UNKNOWN_ERROR; 5432d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner } 5442d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner mCurrentTextureImage->bindToTextureTarget(mTexTarget); 5452d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner if ((error = glGetError()) != GL_NO_ERROR) { 546d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("bindTextureImage: error binding external image: %#04x", error); 5472d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner return UNKNOWN_ERROR; 5482d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner } 549bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 55097eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden 55197eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden // Wait for the new buffer to be ready. 55297eba8904c2f221c42a9473407223a4c3a213f75Andy McFadden return doGLFenceWaitLocked(); 553bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 5549a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis 55545155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopianstatus_t GLConsumer::checkAndUpdateEglStateLocked(bool contextCheck) { 556bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLDisplay dpy = eglGetCurrentDisplay(); 557bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden EGLContext ctx = eglGetCurrentContext(); 55886edf4f6470ee0f108bf40d3c1d23bf0a78c9c38Jamie Gennis 55945155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (!contextCheck) { 56045155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // if this is the first time we're called, mEglDisplay/mEglContext have 56145155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian // never been set, so don't error out (below). 56245155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mEglDisplay == EGL_NO_DISPLAY) { 56345155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian mEglDisplay = dpy; 56445155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 56546a1f6b40e1f7677cd41cd30f729ff66c7c21517Jesse Hall if (mEglContext == EGL_NO_CONTEXT) { 56645155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian mEglContext = ctx; 56745155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 56845155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian } 56945155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian 57045155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mEglDisplay != dpy || dpy == EGL_NO_DISPLAY) { 571d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("checkAndUpdateEglState: invalid current EGLDisplay"); 572bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 573bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 574b3e518c820c7dbe35587bd45c510e4e5e7cfd9c9Mathias Agopian 57545155969dc747d09d267cd1f22baf0eaf886a801Mathias Agopian if (mEglContext != ctx || ctx == EGL_NO_CONTEXT) { 576d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("checkAndUpdateEglState: invalid current EGLContext"); 577bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return INVALID_OPERATION; 5788ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis } 57950c4efc2a44fd312febeda76c8d1a6dc42cee8f8Jamie Gennis 580bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglDisplay = dpy; 581bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden mEglContext = ctx; 582bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden return NO_ERROR; 5838ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis} 5848ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis 58513f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hallvoid GLConsumer::setReleaseFence(const sp<Fence>& fence) { 58613f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall if (fence->isValid() && 58713f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 588c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = addReleaseFence(mCurrentTexture, 5895c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTextureImage->graphicBuffer(), fence); 59013f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall if (err != OK) { 591d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("setReleaseFence: failed to add the fence: %s (%d)", 59213f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall strerror(-err), err); 59313f01cbdbd34779a234bc674df79e23672fd5c0bJesse Hall } 594ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall } 595ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall} 596ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall 5972adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::detachFromContext() { 59874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ATRACE_CALL(); 599d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("detachFromContext"); 60074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis Mutex::Autolock lock(mMutex); 60174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 60274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAbandoned) { 603d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("detachFromContext: abandoned GLConsumer"); 60474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return NO_INIT; 60574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 60674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 60774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (!mAttached) { 608d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("detachFromContext: GLConsumer is not attached to a " 60974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "context"); 61074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 61174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 61274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 61374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 61474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 61574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 61674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) { 617d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("detachFromContext: invalid current EGLDisplay"); 61874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 61974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 62074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 62174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) { 622d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("detachFromContext: invalid current EGLContext"); 62374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 62474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 62574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 62674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (dpy != EGL_NO_DISPLAY && ctx != EGL_NO_CONTEXT) { 62774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis status_t err = syncForReleaseLocked(dpy); 62874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (err != OK) { 62974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return err; 63074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 63174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 63274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis glDeleteTextures(1, &mTexName); 63374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 63474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 63574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglDisplay = EGL_NO_DISPLAY; 63674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglContext = EGL_NO_CONTEXT; 63774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached = false; 63874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 63974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 64074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 64174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 6423f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianstatus_t GLConsumer::attachToContext(uint32_t tex) { 64374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis ATRACE_CALL(); 644d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("attachToContext"); 64574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis Mutex::Autolock lock(mMutex); 64674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 64774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAbandoned) { 648d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("attachToContext: abandoned GLConsumer"); 64974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return NO_INIT; 65074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 65174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 65274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (mAttached) { 653d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("attachToContext: GLConsumer is already attached to a " 65474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis "context"); 65574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 65674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 65774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 65874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 65974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 66074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 66174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (dpy == EGL_NO_DISPLAY) { 662d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("attachToContext: invalid current EGLDisplay"); 66374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 66474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 66574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 66674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis if (ctx == EGL_NO_CONTEXT) { 667d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("attachToContext: invalid current EGLContext"); 66874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return INVALID_OPERATION; 66974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 67074bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 67174bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // We need to bind the texture regardless of whether there's a current 67274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis // buffer. 6733f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian glBindTexture(mTexTarget, GLuint(tex)); 67474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 67574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglDisplay = dpy; 67674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mEglContext = ctx; 67774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mTexName = tex; 67874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis mAttached = true; 67974bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 6805c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (mCurrentTextureImage != NULL) { 6815c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // This may wait for a buffer a second time. This is likely required if 6825c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // this is a different context, since otherwise the wait could be skipped 6835c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // by bouncing through another context. For the same context the extra 6845c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // wait is redundant. 6855c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner status_t err = bindTextureImageLocked(); 6865c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (err != NO_ERROR) { 6875c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner return err; 6885c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 689bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden } 690bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 6915c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner return OK; 692bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden} 693bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 694bf974abe92f7495529916fe0f483f3b56e7c30e3Andy McFadden 6952adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { 696d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("syncForReleaseLocked"); 69774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 69801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { 699ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian if (SyncFeatures::getInstance().useNativeFenceSync()) { 70001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLSyncKHR sync = eglCreateSyncKHR(dpy, 70101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); 70201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (sync == EGL_NO_SYNC_KHR) { 703d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("syncForReleaseLocked: error creating EGL fence: %#x", 70401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglGetError()); 70574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return UNKNOWN_ERROR; 70674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 70701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis glFlush(); 70801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis int fenceFd = eglDupNativeFenceFDANDROID(dpy, sync); 70998ff0597bd9e57ba133d54f8f09841f96955cba1Jamie Gennis eglDestroySyncKHR(dpy, sync); 71001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fenceFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { 711d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("syncForReleaseLocked: error dup'ing native fence " 71201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fd: %#x", eglGetError()); 71301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 71401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 71501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis sp<Fence> fence(new Fence(fenceFd)); 716c5d7b7d323bba8772a9005f7d300ad983a04733aLajos Molnar status_t err = addReleaseFenceLocked(mCurrentTexture, 7175c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTextureImage->graphicBuffer(), fence); 71801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (err != OK) { 719d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("syncForReleaseLocked: error adding release fence: " 72001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "%s (%d)", strerror(-err), err); 72101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return err; 72201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 723ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian } else if (mUseFenceSync && SyncFeatures::getInstance().useFenceSync()) { 72401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLSyncKHR fence = mEglSlots[mCurrentTexture].mEglFence; 72501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fence != EGL_NO_SYNC_KHR) { 72601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // There is already a fence for the current slot. We need to 72701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // wait on that before replacing it with another fence to 72801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // ensure that all outstanding buffer accesses have completed 72901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // before the producer accesses it. 73001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000); 73101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (result == EGL_FALSE) { 732d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("syncForReleaseLocked: error waiting for previous " 73301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fence: %#x", eglGetError()); 73401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 73501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 736d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("syncForReleaseLocked: timeout waiting for previous " 73701dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis "fence"); 73801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return TIMED_OUT; 73901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 74001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglDestroySyncKHR(dpy, fence); 74101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 74274bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 74301dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // Create a fence for the outstanding accesses in the current 74401dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis // OpenGL ES context. 74501dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL); 74601dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis if (fence == EGL_NO_SYNC_KHR) { 747d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("syncForReleaseLocked: error creating fence: %#x", 74801dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis eglGetError()); 74901dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis return UNKNOWN_ERROR; 75001dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis } 75101dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis glFlush(); 75201dbf5539bff4bece3f9bbfa55046b04a8a45e99Jamie Gennis mEglSlots[mCurrentTexture].mEglFence = fence; 75374bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 75474bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis } 75574bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 75674bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis return OK; 75774bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis} 75874bed55fff0132be319bcd1703970516ae28b3a9Jamie Gennis 759d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stozabool GLConsumer::isExternalFormat(PixelFormat format) 7607a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian{ 7617a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian switch (format) { 7627a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // supported YUV formats 7637a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YV12: 7647a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Legacy/deprecated YUV formats 7657a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_SP: 7667a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCrCb_420_SP: 7677a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian case HAL_PIXEL_FORMAT_YCbCr_422_I: 7687a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 7697a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian } 7707a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7717a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian // Any OEM format needs to be considered 7727a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian if (format>=0x100 && format<=0x1FF) 7737a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return true; 7747a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7757a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return false; 7767a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 7777a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianuint32_t GLConsumer::getCurrentTextureTarget() const { 779fb1b5a2f333800574b0da435d1200cf9b13d723fJamie Gennis return mTexTarget; 7807a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 7817a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 7822adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::getTransformMatrix(float mtx[16]) { 783f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis Mutex::Autolock lock(mMutex); 784736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix)); 785736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis} 786736aa9573bb7b78f9c315f396c104491b3639426Jamie Gennis 7872adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::setFilteringEnabled(bool enabled) { 7885c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis Mutex::Autolock lock(mMutex); 789e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian if (mAbandoned) { 790d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("setFilteringEnabled: GLConsumer is abandoned!"); 791e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian return; 792e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian } 7935c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis bool needsRecompute = mFilteringEnabled != enabled; 7945c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis mFilteringEnabled = enabled; 795e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 7965c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (needsRecompute && mCurrentTextureImage==NULL) { 797d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGD("setFilteringEnabled called with mCurrentTextureImage == NULL"); 798e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian } 799e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian 8005c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (needsRecompute && mCurrentTextureImage != NULL) { 801e96e9e1093b5700e9f403a6e2479da7dc36d3b71Mathias Agopian computeCurrentTransformMatrixLocked(); 8025c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 8035c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis} 8045c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis 8052adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::computeCurrentTransformMatrixLocked() { 806d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("computeCurrentTransformMatrixLocked"); 8071a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck sp<GraphicBuffer> buf = (mCurrentTextureImage == nullptr) ? 8081a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck nullptr : mCurrentTextureImage->graphicBuffer(); 8091a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck if (buf == nullptr) { 8101a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck GLC_LOGD("computeCurrentTransformMatrixLocked: " 8111a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck "mCurrentTextureImage is NULL"); 8121a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck } 8131a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck computeTransformMatrix(mCurrentTransformMatrix, buf, 8141a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck isEglImageCroppable(mCurrentCrop) ? Rect::EMPTY_RECT : mCurrentCrop, 8151a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck mCurrentTransform, mFilteringEnabled); 8161a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck} 8171a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck 8181a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reckvoid GLConsumer::computeTransformMatrix(float outTransform[16], 8191a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck const sp<GraphicBuffer>& buf, const Rect& cropRect, uint32_t transform, 8201a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck bool filtering) { 821f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 822a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float xform[16]; 823a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 824a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = mtxIdentity[i]; 825a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 8261a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) { 827a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 828a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipH); 829a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 830a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 831a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 832a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 8331a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) { 834a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 835a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxFlipV); 836a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 837a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 838a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 839a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 8401a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 841a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis float result[16]; 842a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis mtxMul(result, xform, mtxRot90); 843a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis for (int i = 0; i < 16; i++) { 844a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis xform[i] = result[i]; 845a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 846f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis } 847f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 848dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis float mtxBeforeFlipV[16]; 8491a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck if (!cropRect.isEmpty()) { 850dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis float tx = 0.0f, ty = 0.0f, sx = 1.0f, sy = 1.0f; 851dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis float bufferWidth = buf->getWidth(); 852dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis float bufferHeight = buf->getHeight(); 8531a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck float shrinkAmount = 0.0f; 8541a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck if (filtering) { 8551a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck // In order to prevent bilinear sampling beyond the edge of the 8561a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck // crop rectangle we may need to shrink it by 2 texels in each 8571a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck // dimension. Normally this would just need to take 1/2 a texel 8581a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck // off each end, but because the chroma channels of YUV420 images 8591a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck // are subsampled we may need to shrink the crop region by a whole 8601a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck // texel on each side. 8611a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck switch (buf->getPixelFormat()) { 8621a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck case PIXEL_FORMAT_RGBA_8888: 8631a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck case PIXEL_FORMAT_RGBX_8888: 864ff415149dc5a83a4eb5960daf2cb2c310ef89847Romain Guy case PIXEL_FORMAT_RGBA_FP16: 865541f22658ab1617c9d12c98684ab40248df8749bRomain Guy case PIXEL_FORMAT_RGBA_1010102: 8661a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck case PIXEL_FORMAT_RGB_888: 8671a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck case PIXEL_FORMAT_RGB_565: 8681a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck case PIXEL_FORMAT_BGRA_8888: 8691a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck // We know there's no subsampling of any channels, so we 8701a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck // only need to shrink by a half a pixel. 8711a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck shrinkAmount = 0.5; 8721a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck break; 8731a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck 8741a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck default: 8751a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck // If we don't recognize the format, we must assume the 8761a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck // worst case (that we care about), which is YUV420. 8771a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck shrinkAmount = 1.0; 8781a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck break; 8795c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 8801a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck } 8815c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis 8821a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck // Only shrink the dimensions that are not the size of the buffer. 8831a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck if (cropRect.width() < bufferWidth) { 8841a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck tx = (float(cropRect.left) + shrinkAmount) / bufferWidth; 8851a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck sx = (float(cropRect.width()) - (2.0f * shrinkAmount)) / 8861a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck bufferWidth; 8871a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck } 8881a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck if (cropRect.height() < bufferHeight) { 8891a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck ty = (float(bufferHeight - cropRect.bottom) + shrinkAmount) / 8901a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck bufferHeight; 8911a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck sy = (float(cropRect.height()) - (2.0f * shrinkAmount)) / 8921a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck bufferHeight; 8935c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 894dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis float crop[16] = { 895dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis sx, 0, 0, 0, 896dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 0, sy, 0, 0, 897dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 0, 0, 1, 0, 898dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis tx, ty, 0, 1, 899dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis }; 900dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis 901dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis mtxMul(mtxBeforeFlipV, crop, xform); 902dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis } else { 903dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis for (int i = 0; i < 16; i++) { 904dbe9245e2e362b12e184cd33b9a27b0901f81244Jamie Gennis mtxBeforeFlipV[i] = xform[i]; 9055c1139fea3cc0fd9847a6594d853a458152b2fbcJamie Gennis } 906a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis } 907a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis 908a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // SurfaceFlinger expects the top of its window textures to be at a Y 9092adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden // coordinate of 0, so GLConsumer must behave the same way. We don't 910a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // want to expose this to applications, however, so we must add an 911a214c64d7fb3baf9138cc5314f2111ecf5056c6cJamie Gennis // additional vertical flip to the transform after all the other transforms. 9121a61da5e28fa16ad556a58193c8bbeb32a5f636dJohn Reck mtxMul(outTransform, mtxFlipV, mtxBeforeFlipV); 913f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 914f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 9152adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddennsecs_t GLConsumer::getTimestamp() { 916d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("getTimestamp"); 9171d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala Mutex::Autolock lock(mMutex); 9181d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala return mCurrentTimestamp; 9191d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala} 9201d01a12e7150be569557b64da9b8663c62c13594Eino-Ville Talvala 921bb09b436fa119ad8b97f1bf5c04cc5aa10b5f1f0Courtney Goeltzenleuchterandroid_dataspace GLConsumer::getCurrentDataSpace() { 922bb09b436fa119ad8b97f1bf5c04cc5aa10b5f1f0Courtney Goeltzenleuchter GLC_LOGV("getCurrentDataSpace"); 923bb09b436fa119ad8b97f1bf5c04cc5aa10b5f1f0Courtney Goeltzenleuchter Mutex::Autolock lock(mMutex); 924bb09b436fa119ad8b97f1bf5c04cc5aa10b5f1f0Courtney Goeltzenleuchter return mCurrentDataSpace; 925bb09b436fa119ad8b97f1bf5c04cc5aa10b5f1f0Courtney Goeltzenleuchter} 926bb09b436fa119ad8b97f1bf5c04cc5aa10b5f1f0Courtney Goeltzenleuchter 927d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stozauint64_t GLConsumer::getFrameNumber() { 928d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("getFrameNumber"); 929d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala Mutex::Autolock lock(mMutex); 930d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala return mCurrentFrameNumber; 931d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala} 932d171da973de3c6b30263011334fdcd916739144fEino-Ville Talvala 93306d63de03cb2a551ca99608f5aa0c4f3e200b0fcChia-I Wusp<GraphicBuffer> GLConsumer::getCurrentBuffer(int* outSlot) const { 9347a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 93506d63de03cb2a551ca99608f5aa0c4f3e200b0fcChia-I Wu 93606d63de03cb2a551ca99608f5aa0c4f3e200b0fcChia-I Wu if (outSlot != nullptr) { 93706d63de03cb2a551ca99608f5aa0c4f3e200b0fcChia-I Wu *outSlot = mCurrentTexture; 93806d63de03cb2a551ca99608f5aa0c4f3e200b0fcChia-I Wu } 93906d63de03cb2a551ca99608f5aa0c4f3e200b0fcChia-I Wu 94006d63de03cb2a551ca99608f5aa0c4f3e200b0fcChia-I Wu return (mCurrentTextureImage == nullptr) ? 9415c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner NULL : mCurrentTextureImage->graphicBuffer(); 9427a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 9437a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 9442adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenRect GLConsumer::getCurrentCrop() const { 9457a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 946016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 947016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam Rect outCrop = mCurrentCrop; 948016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { 949d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza uint32_t newWidth = static_cast<uint32_t>(mCurrentCrop.width()); 950d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza uint32_t newHeight = static_cast<uint32_t>(mCurrentCrop.height()); 951016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 952016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam if (newWidth * mDefaultHeight > newHeight * mDefaultWidth) { 953016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam newWidth = newHeight * mDefaultWidth / mDefaultHeight; 954d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("too wide: newWidth = %d", newWidth); 955016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } else if (newWidth * mDefaultHeight < newHeight * mDefaultWidth) { 956016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam newHeight = newWidth * mDefaultHeight / mDefaultWidth; 957d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("too tall: newHeight = %d", newHeight); 958016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 959016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 960d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza uint32_t currentWidth = static_cast<uint32_t>(mCurrentCrop.width()); 961d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza uint32_t currentHeight = static_cast<uint32_t>(mCurrentCrop.height()); 962d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza 963016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The crop is too wide 964d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza if (newWidth < currentWidth) { 965ec4cb387502d5bd09e49b55605cf679fe3a0207aDan Stoza uint32_t dw = currentWidth - newWidth; 966ec4cb387502d5bd09e49b55605cf679fe3a0207aDan Stoza auto halfdw = dw / 2; 967ec4cb387502d5bd09e49b55605cf679fe3a0207aDan Stoza outCrop.left += halfdw; 968ec4cb387502d5bd09e49b55605cf679fe3a0207aDan Stoza // Not halfdw because it would subtract 1 too few when dw is odd 969ec4cb387502d5bd09e49b55605cf679fe3a0207aDan Stoza outCrop.right -= (dw - halfdw); 970016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam // The crop is too tall 971d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza } else if (newHeight < currentHeight) { 972ec4cb387502d5bd09e49b55605cf679fe3a0207aDan Stoza uint32_t dh = currentHeight - newHeight; 973ec4cb387502d5bd09e49b55605cf679fe3a0207aDan Stoza auto halfdh = dh / 2; 974ec4cb387502d5bd09e49b55605cf679fe3a0207aDan Stoza outCrop.top += halfdh; 975ec4cb387502d5bd09e49b55605cf679fe3a0207aDan Stoza // Not halfdh because it would subtract 1 too few when dh is odd 976ec4cb387502d5bd09e49b55605cf679fe3a0207aDan Stoza outCrop.bottom -= (dh - halfdh); 977016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 978016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 979d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("getCurrentCrop final crop [%d,%d,%d,%d]", 980016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.left, outCrop.top, 981016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam outCrop.right,outCrop.bottom); 982016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam } 983016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam 984016c8cbce4dde21f2703b9865f52d16b8d5d5ae2Daniel Lam return outCrop; 9857a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 9867a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 9872adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenuint32_t GLConsumer::getCurrentTransform() const { 9887a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian Mutex::Autolock lock(mMutex); 9897a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian return mCurrentTransform; 9907a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian} 9917a042bf324fe3f3d5d4085fda21fe50dc0c362b4Mathias Agopian 9922adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenuint32_t GLConsumer::getCurrentScalingMode() const { 9937734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian Mutex::Autolock lock(mMutex); 9947734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian return mCurrentScalingMode; 9957734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian} 9967734ebfe47f42f980c1b44c1f284a91d8ad1d6c7Mathias Agopian 9972adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddensp<Fence> GLConsumer::getCurrentFence() const { 998dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall Mutex::Autolock lock(mMutex); 999dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall return mCurrentFence; 1000dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall} 1001dc5b485f74edf2d2f31c62054eb6c180421a3adeJesse Hall 10023d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Andersonstd::shared_ptr<FenceTime> GLConsumer::getCurrentFenceTime() const { 10033d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson Mutex::Autolock lock(mMutex); 10043d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson return mCurrentFenceTime; 10053d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson} 10063d4039d7a291cd9b6f2dd4b46fcdb576f2db3356Brian Anderson 10072adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::doGLFenceWait() const { 100861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis Mutex::Autolock lock(mMutex); 10093941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis return doGLFenceWaitLocked(); 10103941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis} 10113941cb240d438bfdebe24920bb2ada86456a0bf9Jamie Gennis 10122adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::doGLFenceWaitLocked() const { 101361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 101461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLDisplay dpy = eglGetCurrentDisplay(); 101561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLContext ctx = eglGetCurrentContext(); 101661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 101761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (mEglDisplay != dpy || mEglDisplay == EGL_NO_DISPLAY) { 1018d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("doGLFenceWait: invalid current EGLDisplay"); 101961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return INVALID_OPERATION; 102061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 102161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 102261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (mEglContext != ctx || mEglContext == EGL_NO_CONTEXT) { 1023d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("doGLFenceWait: invalid current EGLContext"); 102461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return INVALID_OPERATION; 102561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 102661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 10271df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis if (mCurrentFence->isValid()) { 1028ca08833d5ea99130797e10ad68a651b50e99da74Mathias Agopian if (SyncFeatures::getInstance().useWaitSync()) { 102961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // Create an EGLSyncKHR from the current fence. 103061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis int fenceFd = mCurrentFence->dup(); 103161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (fenceFd == -1) { 1032d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("doGLFenceWait: error dup'ing fence fd: %d", errno); 103361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return -errno; 103461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 103561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLint attribs[] = { 103661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd, 103761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_NONE 103861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis }; 103961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLSyncKHR sync = eglCreateSyncKHR(dpy, 104061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGL_SYNC_NATIVE_FENCE_ANDROID, attribs); 104161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (sync == EGL_NO_SYNC_KHR) { 104261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis close(fenceFd); 1043d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("doGLFenceWait: error creating EGL fence: %#x", 104461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglGetError()); 104561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return UNKNOWN_ERROR; 104661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 104761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 104861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // XXX: The spec draft is inconsistent as to whether this should 104961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // return an EGLint or void. Ignore the return value for now, as 105061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis // it's not strictly needed. 10512bb716871cf8bfadfff1193ed798da3bffc1f8ecMathias Agopian eglWaitSyncKHR(dpy, sync, 0); 105261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis EGLint eglErr = eglGetError(); 105361e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglDestroySyncKHR(dpy, sync); 105461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (eglErr != EGL_SUCCESS) { 1055d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("doGLFenceWait: error waiting for EGL fence: %#x", 105661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis eglErr); 105761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return UNKNOWN_ERROR; 105861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 105961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } else { 1060ea74d3b78d607cde17790a7bb83e6f68ffd34cfdMathias Agopian status_t err = mCurrentFence->waitForever( 10612adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden "GLConsumer::doGLFenceWaitLocked"); 106261e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis if (err != NO_ERROR) { 1063d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGE("doGLFenceWait: error waiting for fence: %d", err); 106461e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return err; 106561e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 106661e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 106761e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis } 106861e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 106961e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis return NO_ERROR; 107061e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis} 107161e04b92bdeafc6fca89052d14dab1bd0c384a71Jamie Gennis 10722adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::freeBufferLocked(int slotIndex) { 1073d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("freeBufferLocked: slotIndex=%d", slotIndex); 10749abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam if (slotIndex == mCurrentTexture) { 10759abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; 10769abe1ebc9575dc5a19bf1dfce6e9b02e03374457Daniel Lam } 10775c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglSlots[slotIndex].mEglImage.clear(); 10789fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase::freeBufferLocked(slotIndex); 1079fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis} 1080fa5b40ebb8923133df12dc70591bfe35b3f1c9b3Jamie Gennis 10812adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::abandonLocked() { 1082d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza GLC_LOGV("abandonLocked"); 10835c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCurrentTextureImage.clear(); 10849fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis ConsumerBase::abandonLocked(); 10857b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis} 10867b305fffc39d0fe0926e7fd2d7f6a524fbce62b7Jamie Gennis 10872adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenvoid GLConsumer::setName(const String8& name) { 1088eae59d2ea77ef57aab203fb185a880ce37ac38d6Daniel Lam Mutex::Autolock _l(mMutex); 108965d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos if (mAbandoned) { 109065d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos GLC_LOGE("setName: GLConsumer is abandoned!"); 109165d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos return; 109265d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos } 1093fa28c35c21d1bf8b38f541758c291bc17a2d7270Jamie Gennis mName = name; 1094db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian mConsumer->setConsumerName(name); 1095b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 1096b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 1097d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stozastatus_t GLConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) { 1098b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 109965d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos if (mAbandoned) { 110065d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos GLC_LOGE("setDefaultBufferFormat: GLConsumer is abandoned!"); 110165d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos return NO_INIT; 110265d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos } 1103db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setDefaultBufferFormat(defaultFormat); 1104b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 1105b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 11065b75a513e431c097ae704cba2f7affa6bfaecec9Eino-Ville Talvalastatus_t GLConsumer::setDefaultBufferDataSpace( 11075b75a513e431c097ae704cba2f7affa6bfaecec9Eino-Ville Talvala android_dataspace defaultDataSpace) { 11085b75a513e431c097ae704cba2f7affa6bfaecec9Eino-Ville Talvala Mutex::Autolock lock(mMutex); 110965d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos if (mAbandoned) { 111065d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos GLC_LOGE("setDefaultBufferDataSpace: GLConsumer is abandoned!"); 111165d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos return NO_INIT; 111265d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos } 11135b75a513e431c097ae704cba2f7affa6bfaecec9Eino-Ville Talvala return mConsumer->setDefaultBufferDataSpace(defaultDataSpace); 11145b75a513e431c097ae704cba2f7affa6bfaecec9Eino-Ville Talvala} 11155b75a513e431c097ae704cba2f7affa6bfaecec9Eino-Ville Talvala 11162adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setConsumerUsageBits(uint32_t usage) { 1117b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 111865d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos if (mAbandoned) { 111965d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos GLC_LOGE("setConsumerUsageBits: GLConsumer is abandoned!"); 112065d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos return NO_INIT; 112165d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos } 112285b217668d6840c8e6a109adfb99461313676f8dEino-Ville Talvala usage |= DEFAULT_USAGE_FLAGS; 1123db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setConsumerUsageBits(usage); 1124b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 1125b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 11262adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenstatus_t GLConsumer::setTransformHint(uint32_t hint) { 1127b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam Mutex::Autolock lock(mMutex); 112865d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos if (mAbandoned) { 112965d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos GLC_LOGE("setTransformHint: GLConsumer is abandoned!"); 113065d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos return NO_INIT; 113165d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos } 1132db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian return mConsumer->setTransformHint(hint); 1133b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam} 1134b267579ba8dfe3f47d2a481c5a3c2254e3d565a1Daniel Lam 113519e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballosstatus_t GLConsumer::setMaxAcquiredBufferCount(int maxAcquiredBuffers) { 113619e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos Mutex::Autolock lock(mMutex); 113765d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos if (mAbandoned) { 113865d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos GLC_LOGE("setMaxAcquiredBufferCount: GLConsumer is abandoned!"); 113965d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos return NO_INIT; 114065d9f6d63ab3bad1d835df14c662028a748eb3c5Pablo Ceballos } 114119e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos return mConsumer->setMaxAcquiredBufferCount(maxAcquiredBuffers); 114219e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos} 114319e3e06e3c65a7c001a6fe0971744ba5ff536515Pablo Ceballos 114474d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid GLConsumer::dumpLocked(String8& result, const char* prefix) const 114568c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian{ 114674d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian result.appendFormat( 11479fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis "%smTexName=%d mCurrentTexture=%d\n" 11489fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis "%smCurrentCrop=[%d,%d,%d,%d] mCurrentTransform=%#x\n", 11499fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis prefix, mTexName, mCurrentTexture, prefix, mCurrentCrop.left, 11509fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom, 11519fea3421ffddf6480f57f55a25936a886043d909Jamie Gennis mCurrentTransform); 115268c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 115374d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian ConsumerBase::dumpLocked(result, prefix); 115468c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian} 115568c7794183a7dbfe3b20d4ce832f8eb79c2c619aMathias Agopian 1156f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennisstatic void mtxMul(float out[16], const float a[16], const float b[16]) { 1157f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3]; 1158f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3]; 1159f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3]; 1160f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3]; 1161f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1162f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7]; 1163f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7]; 1164f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7]; 1165f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7]; 1166f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1167f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11]; 1168f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11]; 1169f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11]; 1170f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11]; 1171f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 1172f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15]; 1173f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15]; 1174f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15]; 1175f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15]; 1176f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis} 1177f238e28500ca756fbd9e323f728ce7c8dda59475Jamie Gennis 11785c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric PennerGLConsumer::EglImage::EglImage(sp<GraphicBuffer> graphicBuffer) : 11795c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mGraphicBuffer(graphicBuffer), 11805c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglImage(EGL_NO_IMAGE_KHR), 118160d6922a011fe18c111b8d30fb6ef1f655b6b15ePablo Ceballos mEglDisplay(EGL_NO_DISPLAY), 118260d6922a011fe18c111b8d30fb6ef1f655b6b15ePablo Ceballos mCropRect(Rect::EMPTY_RECT) { 11835c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner} 11845c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 11855c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric PennerGLConsumer::EglImage::~EglImage() { 11865c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (mEglImage != EGL_NO_IMAGE_KHR) { 11875c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (!eglDestroyImageKHR(mEglDisplay, mEglImage)) { 11885c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner ALOGE("~EglImage: eglDestroyImageKHR failed"); 11895c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 119078be65e7bf6898c6afa55c9016f331ab1aa2503aMichael Lentine eglTerminate(mEglDisplay); 11915c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 11925c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner} 11935c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 11945c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Pennerstatus_t GLConsumer::EglImage::createIfNeeded(EGLDisplay eglDisplay, 11952d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner const Rect& cropRect, 11962d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner bool forceCreation) { 11975c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // If there's an image and it's no longer valid, destroy it. 11985c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner bool haveImage = mEglImage != EGL_NO_IMAGE_KHR; 11995c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner bool displayInvalid = mEglDisplay != eglDisplay; 12005c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner bool cropInvalid = hasEglAndroidImageCrop() && mCropRect != cropRect; 12012d14a0ed4f5861bfa67e9db138ffdc70d2d5e6e4Eric Penner if (haveImage && (displayInvalid || cropInvalid || forceCreation)) { 12025c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (!eglDestroyImageKHR(mEglDisplay, mEglImage)) { 12035c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner ALOGE("createIfNeeded: eglDestroyImageKHR failed"); 12045c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 120578be65e7bf6898c6afa55c9016f331ab1aa2503aMichael Lentine eglTerminate(mEglDisplay); 12065c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglImage = EGL_NO_IMAGE_KHR; 12075c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglDisplay = EGL_NO_DISPLAY; 12085c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 12095c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 12105c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // If there's no image, create one. 12115c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (mEglImage == EGL_NO_IMAGE_KHR) { 12125c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglDisplay = eglDisplay; 12135c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCropRect = cropRect; 12145c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglImage = createImage(mEglDisplay, mGraphicBuffer, mCropRect); 12155c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 12165c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 12175c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // Fail if we can't create a valid image. 12185c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (mEglImage == EGL_NO_IMAGE_KHR) { 12195c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mEglDisplay = EGL_NO_DISPLAY; 12205c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner mCropRect.makeInvalid(); 12215c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner const sp<GraphicBuffer>& buffer = mGraphicBuffer; 12225c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner ALOGE("Failed to create image. size=%ux%u st=%u usage=0x%x fmt=%d", 12235c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner buffer->getWidth(), buffer->getHeight(), buffer->getStride(), 12245c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner buffer->getUsage(), buffer->getPixelFormat()); 12255c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner return UNKNOWN_ERROR; 12265c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 12275c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 12285c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner return OK; 12295c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner} 12305c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 12315c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Pennervoid GLConsumer::EglImage::bindToTextureTarget(uint32_t texTarget) { 1232d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza glEGLImageTargetTexture2DOES(texTarget, 1233d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza static_cast<GLeglImageOES>(mEglImage)); 12345c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner} 12355c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 12365c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric PennerEGLImageKHR GLConsumer::EglImage::createImage(EGLDisplay dpy, 12375c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner const sp<GraphicBuffer>& graphicBuffer, const Rect& crop) { 1238d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza EGLClientBuffer cbuf = 1239d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza static_cast<EGLClientBuffer>(graphicBuffer->getNativeBuffer()); 1240aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner const bool createProtectedImage = 1241aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner (graphicBuffer->getUsage() & GRALLOC_USAGE_PROTECTED) && 1242aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner hasEglProtectedContent(); 12435c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGLint attrs[] = { 12445c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 12455c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGL_IMAGE_CROP_LEFT_ANDROID, crop.left, 12465c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGL_IMAGE_CROP_TOP_ANDROID, crop.top, 12475c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGL_IMAGE_CROP_RIGHT_ANDROID, crop.right, 12485c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGL_IMAGE_CROP_BOTTOM_ANDROID, crop.bottom, 1249aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner createProtectedImage ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE, 1250aec8697fcaa8bb30e335f7850cffdd0364c35532Craig Donner createProtectedImage ? EGL_TRUE : EGL_NONE, 12515c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGL_NONE, 12525c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner }; 12535c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (!crop.isValid()) { 1254a94d940c75456714b1c4425dde1e44802cb838f7Craig Donner // No crop rect to set, so leave the crop out of the attrib array. Make 1255a94d940c75456714b1c4425dde1e44802cb838f7Craig Donner // sure to propagate the protected content attrs if they are set. 1256a94d940c75456714b1c4425dde1e44802cb838f7Craig Donner attrs[2] = attrs[10]; 1257a94d940c75456714b1c4425dde1e44802cb838f7Craig Donner attrs[3] = attrs[11]; 1258a94d940c75456714b1c4425dde1e44802cb838f7Craig Donner attrs[4] = EGL_NONE; 12595c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } else if (!isEglImageCroppable(crop)) { 12605c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // The crop rect is not at the origin, so we can't set the crop on the 12615c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // EGLImage because that's not allowed by the EGL_ANDROID_image_crop 12625c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // extension. In the future we can add a layered extension that 12635c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner // removes this restriction if there is hardware that can support it. 1264a94d940c75456714b1c4425dde1e44802cb838f7Craig Donner attrs[2] = attrs[10]; 1265a94d940c75456714b1c4425dde1e44802cb838f7Craig Donner attrs[3] = attrs[11]; 1266a94d940c75456714b1c4425dde1e44802cb838f7Craig Donner attrs[4] = EGL_NONE; 12675c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 126878be65e7bf6898c6afa55c9016f331ab1aa2503aMichael Lentine eglInitialize(dpy, 0, 0); 12695c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, 12705c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs); 12715c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner if (image == EGL_NO_IMAGE_KHR) { 12725c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner EGLint error = eglGetError(); 12735c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner ALOGE("error creating EGLImage: %#x", error); 127478be65e7bf6898c6afa55c9016f331ab1aa2503aMichael Lentine eglTerminate(dpy); 12755c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner } 12765c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner return image; 12775c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner} 12785c3d243fcca6d0678bcbb0461bbbe0b63f35212cEric Penner 12798ba32fade11abb73f3fd47ea0953c9528eb5b91fJamie Gennis}; // namespace android 1280