diff options
Diffstat (limited to 'libs/gui/GLConsumer.cpp')
-rw-r--r-- | libs/gui/GLConsumer.cpp | 307 |
1 files changed, 95 insertions, 212 deletions
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp index 59e78cc6bf..885efec9b9 100644 --- a/libs/gui/GLConsumer.cpp +++ b/libs/gui/GLConsumer.cpp @@ -31,6 +31,8 @@ #include <hardware/hardware.h> +#include <math/mat4.h> + #include <gui/BufferItem.h> #include <gui/GLConsumer.h> #include <gui/ISurfaceComposer.h> @@ -75,33 +77,7 @@ static const struct { "_______________" }; -// Transform matrices -static float mtxIdentity[16] = { - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1, -}; -static float mtxFlipH[16] = { - -1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 1, 0, 0, 1, -}; -static float mtxFlipV[16] = { - 1, 0, 0, 0, - 0, -1, 0, 0, - 0, 0, 1, 0, - 0, 1, 0, 1, -}; -static float mtxRot90[16] = { - 0, 1, 0, 0, - -1, 0, 0, 0, - 0, 0, 1, 0, - 1, 0, 0, 1, -}; - -static void mtxMul(float out[16], const float a[16], const float b[16]); +static const mat4 mtxIdentity; Mutex GLConsumer::sStaticInitLock; sp<GraphicBuffer> GLConsumer::sReleasedTexImageBuffer; @@ -173,7 +149,7 @@ GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex, { GLC_LOGV("GLConsumer"); - memcpy(mCurrentTransformMatrix, mtxIdentity, + memcpy(mCurrentTransformMatrix, mtxIdentity.asArray(), sizeof(mCurrentTransformMatrix)); mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS); @@ -202,7 +178,7 @@ GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t texTarget, { GLC_LOGV("GLConsumer"); - memcpy(mCurrentTransformMatrix, mtxIdentity, + memcpy(mCurrentTransformMatrix, mtxIdentity.asArray(), sizeof(mCurrentTransformMatrix)); mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS); @@ -315,7 +291,7 @@ status_t GLConsumer::releaseTexImage() { return err; } - if (mReleasedTexImage == nullptr) { + if (mReleasedTexImage == NULL) { mReleasedTexImage = new EglImage(getDebugTexImageBuffer()); } @@ -345,7 +321,7 @@ status_t GLConsumer::releaseTexImage() { sp<GraphicBuffer> GLConsumer::getDebugTexImageBuffer() { Mutex::Autolock _l(sStaticInitLock); - if (CC_UNLIKELY(sReleasedTexImageBuffer == nullptr)) { + if (CC_UNLIKELY(sReleasedTexImageBuffer == NULL)) { // The first time, create the debug texture in case the application // continues to use it. sp<GraphicBuffer> buffer = new GraphicBuffer( @@ -381,7 +357,7 @@ status_t GLConsumer::acquireBufferLocked(BufferItem *item, // If item->mGraphicBuffer is not null, this buffer has not been acquired // before, so any prior EglImage created is using a stale buffer. This // replaces any old EglImage with a new one (using the new buffer). - if (item->mGraphicBuffer != nullptr) { + if (item->mGraphicBuffer != NULL) { int slot = item->mSlot; mEglSlots[slot].mEglImage = new EglImage(item->mGraphicBuffer); } @@ -455,7 +431,7 @@ status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item, GLC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", mCurrentTexture, mCurrentTextureImage != NULL ? - mCurrentTextureImage->graphicBufferHandle() : nullptr, + mCurrentTextureImage->graphicBufferHandle() : 0, slot, mSlots[slot].mGraphicBuffer->handle); // Hang onto the pointer so that it isn't freed in the call to @@ -515,7 +491,7 @@ status_t GLConsumer::bindTextureImageLocked() { glBindTexture(mTexTarget, mTexName); if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && - mCurrentTextureImage == nullptr) { + mCurrentTextureImage == NULL) { GLC_LOGE("bindTextureImage: no currently-bound texture"); return NO_INIT; } @@ -679,7 +655,7 @@ status_t GLConsumer::attachToContext(uint32_t tex) { mTexName = tex; mAttached = true; - if (mCurrentTextureImage != nullptr) { + if (mCurrentTextureImage != NULL) { // This may wait for a buffer a second time. This is likely required if // this is a different context, since otherwise the wait could be skipped // by bouncing through another context. For the same context the extra @@ -700,7 +676,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { if (SyncFeatures::getInstance().useNativeFenceSync()) { EGLSyncKHR sync = eglCreateSyncKHR(dpy, - EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr); + EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); if (sync == EGL_NO_SYNC_KHR) { GLC_LOGE("syncForReleaseLocked: error creating EGL fence: %#x", eglGetError()); @@ -744,7 +720,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { // Create a fence for the outstanding accesses in the current // OpenGL ES context. - fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, nullptr); + fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL); if (fence == EGL_NO_SYNC_KHR) { GLC_LOGE("syncForReleaseLocked: error creating fence: %#x", eglGetError()); @@ -758,25 +734,6 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) { return OK; } -bool GLConsumer::isExternalFormat(PixelFormat format) -{ - switch (format) { - // supported YUV formats - case HAL_PIXEL_FORMAT_YV12: - // Legacy/deprecated YUV formats - case HAL_PIXEL_FORMAT_YCbCr_422_SP: - case HAL_PIXEL_FORMAT_YCrCb_420_SP: - case HAL_PIXEL_FORMAT_YCbCr_422_I: - return true; - } - - // Any OEM format needs to be considered - if (format>=0x100 && format<=0x1FF) - return true; - - return false; -} - uint32_t GLConsumer::getCurrentTextureTarget() const { return mTexTarget; } @@ -795,11 +752,11 @@ void GLConsumer::setFilteringEnabled(bool enabled) { bool needsRecompute = mFilteringEnabled != enabled; mFilteringEnabled = enabled; - if (needsRecompute && mCurrentTextureImage==nullptr) { + if (needsRecompute && mCurrentTextureImage==NULL) { GLC_LOGD("setFilteringEnabled called with mCurrentTextureImage == NULL"); } - if (needsRecompute && mCurrentTextureImage != nullptr) { + if (needsRecompute && mCurrentTextureImage != NULL) { computeCurrentTransformMatrixLocked(); } } @@ -820,34 +777,37 @@ void GLConsumer::computeCurrentTransformMatrixLocked() { void GLConsumer::computeTransformMatrix(float outTransform[16], const sp<GraphicBuffer>& buf, const Rect& cropRect, uint32_t transform, bool filtering) { - - float xform[16]; - for (int i = 0; i < 16; i++) { - xform[i] = mtxIdentity[i]; - } + // Transform matrices + static const mat4 mtxFlipH( + -1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 1, 0, 0, 1 + ); + static const mat4 mtxFlipV( + 1, 0, 0, 0, + 0, -1, 0, 0, + 0, 0, 1, 0, + 0, 1, 0, 1 + ); + static const mat4 mtxRot90( + 0, 1, 0, 0, + -1, 0, 0, 0, + 0, 0, 1, 0, + 1, 0, 0, 1 + ); + + mat4 xform; if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) { - float result[16]; - mtxMul(result, xform, mtxFlipH); - for (int i = 0; i < 16; i++) { - xform[i] = result[i]; - } + xform *= mtxFlipH; } if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) { - float result[16]; - mtxMul(result, xform, mtxFlipV); - for (int i = 0; i < 16; i++) { - xform[i] = result[i]; - } + xform *= mtxFlipV; } if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) { - float result[16]; - mtxMul(result, xform, mtxRot90); - for (int i = 0; i < 16; i++) { - xform[i] = result[i]; - } + xform *= mtxRot90; } - float mtxBeforeFlipV[16]; if (!cropRect.isEmpty()) { float tx = 0.0f, ty = 0.0f, sx = 1.0f, sy = 1.0f; float bufferWidth = buf->getWidth(); @@ -893,25 +853,63 @@ void GLConsumer::computeTransformMatrix(float outTransform[16], sy = (float(cropRect.height()) - (2.0f * shrinkAmount)) / bufferHeight; } - float crop[16] = { + + mat4 crop( sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, 1, 0, - tx, ty, 0, 1, - }; - - mtxMul(mtxBeforeFlipV, crop, xform); - } else { - for (int i = 0; i < 16; i++) { - mtxBeforeFlipV[i] = xform[i]; - } + tx, ty, 0, 1 + ); + xform = crop * xform; } // SurfaceFlinger expects the top of its window textures to be at a Y // coordinate of 0, so GLConsumer must behave the same way. We don't // want to expose this to applications, however, so we must add an // additional vertical flip to the transform after all the other transforms. - mtxMul(outTransform, mtxFlipV, mtxBeforeFlipV); + xform = mtxFlipV * xform; + + memcpy(outTransform, xform.asArray(), sizeof(xform)); +} + +Rect GLConsumer::scaleDownCrop(const Rect& crop, uint32_t bufferWidth, uint32_t bufferHeight) { + Rect outCrop = crop; + + uint32_t newWidth = static_cast<uint32_t>(crop.width()); + uint32_t newHeight = static_cast<uint32_t>(crop.height()); + + if (newWidth * bufferHeight > newHeight * bufferWidth) { + newWidth = newHeight * bufferWidth / bufferHeight; + ALOGV("too wide: newWidth = %d", newWidth); + } else if (newWidth * bufferHeight < newHeight * bufferWidth) { + newHeight = newWidth * bufferHeight / bufferWidth; + ALOGV("too tall: newHeight = %d", newHeight); + } + + uint32_t currentWidth = static_cast<uint32_t>(crop.width()); + uint32_t currentHeight = static_cast<uint32_t>(crop.height()); + + // The crop is too wide + if (newWidth < currentWidth) { + uint32_t dw = currentWidth - newWidth; + auto halfdw = dw / 2; + outCrop.left += halfdw; + // Not halfdw because it would subtract 1 too few when dw is odd + outCrop.right -= (dw - halfdw); + // The crop is too tall + } else if (newHeight < currentHeight) { + uint32_t dh = currentHeight - newHeight; + auto halfdh = dh / 2; + outCrop.top += halfdh; + // Not halfdh because it would subtract 1 too few when dh is odd + outCrop.bottom -= (dh - halfdh); + } + + ALOGV("getCurrentCrop final crop [%d,%d,%d,%d]", + outCrop.left, outCrop.top, + outCrop.right,outCrop.bottom); + + return outCrop; } nsecs_t GLConsumer::getTimestamp() { @@ -940,50 +938,14 @@ sp<GraphicBuffer> GLConsumer::getCurrentBuffer(int* outSlot) const { } return (mCurrentTextureImage == nullptr) ? - nullptr : mCurrentTextureImage->graphicBuffer(); + NULL : mCurrentTextureImage->graphicBuffer(); } Rect GLConsumer::getCurrentCrop() const { Mutex::Autolock lock(mMutex); - - Rect outCrop = mCurrentCrop; - if (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) { - uint32_t newWidth = static_cast<uint32_t>(mCurrentCrop.width()); - uint32_t newHeight = static_cast<uint32_t>(mCurrentCrop.height()); - - if (newWidth * mDefaultHeight > newHeight * mDefaultWidth) { - newWidth = newHeight * mDefaultWidth / mDefaultHeight; - GLC_LOGV("too wide: newWidth = %d", newWidth); - } else if (newWidth * mDefaultHeight < newHeight * mDefaultWidth) { - newHeight = newWidth * mDefaultHeight / mDefaultWidth; - GLC_LOGV("too tall: newHeight = %d", newHeight); - } - - uint32_t currentWidth = static_cast<uint32_t>(mCurrentCrop.width()); - uint32_t currentHeight = static_cast<uint32_t>(mCurrentCrop.height()); - - // The crop is too wide - if (newWidth < currentWidth) { - uint32_t dw = currentWidth - newWidth; - auto halfdw = dw / 2; - outCrop.left += halfdw; - // Not halfdw because it would subtract 1 too few when dw is odd - outCrop.right -= (dw - halfdw); - // The crop is too tall - } else if (newHeight < currentHeight) { - uint32_t dh = currentHeight - newHeight; - auto halfdh = dh / 2; - outCrop.top += halfdh; - // Not halfdh because it would subtract 1 too few when dh is odd - outCrop.bottom -= (dh - halfdh); - } - - GLC_LOGV("getCurrentCrop final crop [%d,%d,%d,%d]", - outCrop.left, outCrop.top, - outCrop.right,outCrop.bottom); - } - - return outCrop; + return (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) + ? scaleDownCrop(mCurrentCrop, mDefaultWidth, mDefaultHeight) + : mCurrentCrop; } uint32_t GLConsumer::getCurrentTransform() const { @@ -1006,11 +968,6 @@ std::shared_ptr<FenceTime> GLConsumer::getCurrentFenceTime() const { return mCurrentFenceTime; } -status_t GLConsumer::doGLFenceWait() const { - Mutex::Autolock lock(mMutex); - return doGLFenceWaitLocked(); -} - status_t GLConsumer::doGLFenceWaitLocked() const { EGLDisplay dpy = eglGetCurrentDisplay(); @@ -1027,7 +984,8 @@ status_t GLConsumer::doGLFenceWaitLocked() const { } if (mCurrentFence->isValid()) { - if (SyncFeatures::getInstance().useWaitSync()) { + if (SyncFeatures::getInstance().useWaitSync() && + SyncFeatures::getInstance().useNativeFenceSync()) { // Create an EGLSyncKHR from the current fence. int fenceFd = mCurrentFence->dup(); if (fenceFd == -1) { @@ -1086,61 +1044,8 @@ void GLConsumer::abandonLocked() { ConsumerBase::abandonLocked(); } -void GLConsumer::setName(const String8& name) { - Mutex::Autolock _l(mMutex); - if (mAbandoned) { - GLC_LOGE("setName: GLConsumer is abandoned!"); - return; - } - mName = name; - mConsumer->setConsumerName(name); -} - -status_t GLConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) { - Mutex::Autolock lock(mMutex); - if (mAbandoned) { - GLC_LOGE("setDefaultBufferFormat: GLConsumer is abandoned!"); - return NO_INIT; - } - return mConsumer->setDefaultBufferFormat(defaultFormat); -} - -status_t GLConsumer::setDefaultBufferDataSpace( - android_dataspace defaultDataSpace) { - Mutex::Autolock lock(mMutex); - if (mAbandoned) { - GLC_LOGE("setDefaultBufferDataSpace: GLConsumer is abandoned!"); - return NO_INIT; - } - return mConsumer->setDefaultBufferDataSpace(defaultDataSpace); -} - status_t GLConsumer::setConsumerUsageBits(uint64_t usage) { - Mutex::Autolock lock(mMutex); - if (mAbandoned) { - GLC_LOGE("setConsumerUsageBits: GLConsumer is abandoned!"); - return NO_INIT; - } - usage |= DEFAULT_USAGE_FLAGS; - return mConsumer->setConsumerUsageBits(usage); -} - -status_t GLConsumer::setTransformHint(uint32_t hint) { - Mutex::Autolock lock(mMutex); - if (mAbandoned) { - GLC_LOGE("setTransformHint: GLConsumer is abandoned!"); - return NO_INIT; - } - return mConsumer->setTransformHint(hint); -} - -status_t GLConsumer::setMaxAcquiredBufferCount(int maxAcquiredBuffers) { - Mutex::Autolock lock(mMutex); - if (mAbandoned) { - GLC_LOGE("setMaxAcquiredBufferCount: GLConsumer is abandoned!"); - return NO_INIT; - } - return mConsumer->setMaxAcquiredBufferCount(maxAcquiredBuffers); + return ConsumerBase::setConsumerUsageBits(usage | DEFAULT_USAGE_FLAGS); } void GLConsumer::dumpLocked(String8& result, const char* prefix) const @@ -1155,28 +1060,6 @@ void GLConsumer::dumpLocked(String8& result, const char* prefix) const ConsumerBase::dumpLocked(result, prefix); } -static void mtxMul(float out[16], const float a[16], const float b[16]) { - out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3]; - out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3]; - out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3]; - out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3]; - - out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7]; - out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7]; - out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7]; - out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7]; - - out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11]; - out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11]; - out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11]; - out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11]; - - out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15]; - out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15]; - out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15]; - out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15]; -} - GLConsumer::EglImage::EglImage(sp<GraphicBuffer> graphicBuffer) : mGraphicBuffer(graphicBuffer), mEglImage(EGL_NO_IMAGE_KHR), @@ -1267,7 +1150,7 @@ EGLImageKHR GLConsumer::EglImage::createImage(EGLDisplay dpy, attrs[3] = attrs[11]; attrs[4] = EGL_NONE; } - eglInitialize(dpy, nullptr, nullptr); + eglInitialize(dpy, 0, 0); EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs); if (image == EGL_NO_IMAGE_KHR) { |