Loading libs/gui/BufferItemConsumer.cpp +0 −10 Original line number Diff line number Diff line Loading @@ -49,16 +49,6 @@ BufferItemConsumer::BufferItemConsumer( BufferItemConsumer::~BufferItemConsumer() {} void BufferItemConsumer::setName(const String8& name) { Mutex::Autolock _l(mMutex); if (mAbandoned) { BI_LOGE("setName: BufferItemConsumer is abandoned!"); return; } mName = name; mConsumer->setConsumerName(name); } void BufferItemConsumer::setBufferFreedListener( const wp<BufferFreedListener>& listener) { Mutex::Autolock _l(mMutex); Loading libs/gui/ConsumerBase.cpp +54 −0 Original line number Diff line number Diff line Loading @@ -182,6 +182,16 @@ bool ConsumerBase::isAbandoned() { return mAbandoned; } void ConsumerBase::setName(const String8& name) { Mutex::Autolock _l(mMutex); if (mAbandoned) { CB_LOGE("setName: ConsumerBase is abandoned!"); return; } mName = name; mConsumer->setConsumerName(name); } void ConsumerBase::setFrameAvailableListener( const wp<FrameAvailableListener>& listener) { CB_LOGV("setFrameAvailableListener"); Loading Loading @@ -237,6 +247,50 @@ status_t ConsumerBase::setDefaultBufferDataSpace( return mConsumer->setDefaultBufferDataSpace(defaultDataSpace); } status_t ConsumerBase::setConsumerUsageBits(uint64_t usage) { Mutex::Autolock lock(mMutex); if (mAbandoned) { CB_LOGE("setConsumerUsageBits: ConsumerBase is abandoned!"); return NO_INIT; } return mConsumer->setConsumerUsageBits(usage); } status_t ConsumerBase::setTransformHint(uint32_t hint) { Mutex::Autolock lock(mMutex); if (mAbandoned) { CB_LOGE("setTransformHint: ConsumerBase is abandoned!"); return NO_INIT; } return mConsumer->setTransformHint(hint); } status_t ConsumerBase::setMaxAcquiredBufferCount(int maxAcquiredBuffers) { Mutex::Autolock lock(mMutex); if (mAbandoned) { CB_LOGE("setMaxAcquiredBufferCount: ConsumerBase is abandoned!"); return NO_INIT; } return mConsumer->setMaxAcquiredBufferCount(maxAcquiredBuffers); } sp<NativeHandle> ConsumerBase::getSidebandStream() const { Mutex::Autolock _l(mMutex); if (mAbandoned) { CB_LOGE("getSidebandStream: ConsumerBase is abandoned!"); return nullptr; } sp<NativeHandle> stream; status_t err = mConsumer->getSidebandStream(&stream); if (err != NO_ERROR) { CB_LOGE("failed to get sideband stream: %d", err); return nullptr; } return stream; } status_t ConsumerBase::getOccupancyHistory(bool forceFlush, std::vector<OccupancyTracker::Segment>* outHistory) { Mutex::Autolock _l(mMutex); Loading libs/gui/CpuConsumer.cpp +102 −139 Original line number Diff line number Diff line Loading @@ -18,11 +18,11 @@ #define LOG_TAG "CpuConsumer" //#define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <cutils/compiler.h> #include <utils/Log.h> #include <gui/BufferItem.h> #include <gui/CpuConsumer.h> #include <gui/BufferItem.h> #include <utils/Log.h> #define CC_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__) //#define CC_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__) //#define CC_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__) Loading @@ -44,20 +44,19 @@ CpuConsumer::CpuConsumer(const sp<IGraphicBufferConsumer>& bq, mConsumer->setMaxAcquiredBufferCount(static_cast<int32_t>(maxLockedBuffers)); } CpuConsumer::~CpuConsumer() { // ConsumerBase destructor does all the work. size_t CpuConsumer::findAcquiredBufferLocked(uintptr_t id) const { for (size_t i = 0; i < mMaxLockedBuffers; i++) { const auto& ab = mAcquiredBuffers[i]; // note that this finds AcquiredBuffer::kUnusedId as well if (ab.mLockedBufferId == id) { return i; } void CpuConsumer::setName(const String8& name) { Mutex::Autolock _l(mMutex); if (mAbandoned) { CC_LOGE("setName: CpuConsumer is abandoned!"); return; } mName = name; mConsumer->setConsumerName(name); return mMaxLockedBuffers; // an invalid index } static uintptr_t getLockedBufferId(const CpuConsumer::LockedBuffer& buffer) { return reinterpret_cast<uintptr_t>(buffer.data); } static bool isPossiblyYUV(PixelFormat format) { Loading Loading @@ -88,10 +87,74 @@ static bool isPossiblyYUV(PixelFormat format) { } } status_t CpuConsumer::lockBufferItem(const BufferItem& item, LockedBuffer* outBuffer) const { android_ycbcr ycbcr = android_ycbcr(); PixelFormat format = item.mGraphicBuffer->getPixelFormat(); PixelFormat flexFormat = format; if (isPossiblyYUV(format)) { int fenceFd = item.mFence.get() ? item.mFence->dup() : -1; status_t err = item.mGraphicBuffer->lockAsyncYCbCr(GraphicBuffer::USAGE_SW_READ_OFTEN, item.mCrop, &ycbcr, fenceFd); if (err == OK) { flexFormat = HAL_PIXEL_FORMAT_YCbCr_420_888; if (format != HAL_PIXEL_FORMAT_YCbCr_420_888) { CC_LOGV("locking buffer of format %#x as flex YUV", format); } } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) { CC_LOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)", strerror(-err), err); return err; } } if (ycbcr.y != nullptr) { outBuffer->data = reinterpret_cast<uint8_t*>(ycbcr.y); outBuffer->stride = static_cast<uint32_t>(ycbcr.ystride); outBuffer->dataCb = reinterpret_cast<uint8_t*>(ycbcr.cb); outBuffer->dataCr = reinterpret_cast<uint8_t*>(ycbcr.cr); outBuffer->chromaStride = static_cast<uint32_t>(ycbcr.cstride); outBuffer->chromaStep = static_cast<uint32_t>(ycbcr.chroma_step); } else { // not flexible YUV; try lockAsync void* bufferPointer = nullptr; int fenceFd = item.mFence.get() ? item.mFence->dup() : -1; status_t err = item.mGraphicBuffer->lockAsync(GraphicBuffer::USAGE_SW_READ_OFTEN, item.mCrop, &bufferPointer, fenceFd); if (err != OK) { CC_LOGE("Unable to lock buffer for CPU reading: %s (%d)", strerror(-err), err); return err; } outBuffer->data = reinterpret_cast<uint8_t*>(bufferPointer); outBuffer->stride = item.mGraphicBuffer->getStride(); outBuffer->dataCb = nullptr; outBuffer->dataCr = nullptr; outBuffer->chromaStride = 0; outBuffer->chromaStep = 0; } outBuffer->width = item.mGraphicBuffer->getWidth(); outBuffer->height = item.mGraphicBuffer->getHeight(); outBuffer->format = format; outBuffer->flexFormat = flexFormat; outBuffer->crop = item.mCrop; outBuffer->transform = item.mTransform; outBuffer->scalingMode = item.mScalingMode; outBuffer->timestamp = item.mTimestamp; outBuffer->dataSpace = item.mDataSpace; outBuffer->frameNumber = item.mFrameNumber; return OK; } status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) { status_t err; if (!nativeBuffer) return BAD_VALUE; Mutex::Autolock _l(mMutex); if (mCurrentLockedBuffers == mMaxLockedBuffers) { CC_LOGW("Max buffers have been locked (%zd), cannot lock anymore.", mMaxLockedBuffers); Loading @@ -99,9 +162,6 @@ status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) { } BufferItem b; Mutex::Autolock _l(mMutex); err = acquireBufferLocked(&b, 0); if (err != OK) { if (err == BufferQueue::NO_BUFFER_AVAILABLE) { Loading @@ -112,94 +172,23 @@ status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) { } } int slot = b.mSlot; void *bufferPointer = NULL; android_ycbcr ycbcr = android_ycbcr(); PixelFormat format = mSlots[slot].mGraphicBuffer->getPixelFormat(); PixelFormat flexFormat = format; if (isPossiblyYUV(format)) { if (b.mFence.get()) { err = mSlots[slot].mGraphicBuffer->lockAsyncYCbCr( GraphicBuffer::USAGE_SW_READ_OFTEN, b.mCrop, &ycbcr, b.mFence->dup()); } else { err = mSlots[slot].mGraphicBuffer->lockYCbCr( GraphicBuffer::USAGE_SW_READ_OFTEN, b.mCrop, &ycbcr); } if (err == OK) { bufferPointer = ycbcr.y; flexFormat = HAL_PIXEL_FORMAT_YCbCr_420_888; if (format != HAL_PIXEL_FORMAT_YCbCr_420_888) { CC_LOGV("locking buffer of format %#x as flex YUV", format); } } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) { CC_LOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)", strerror(-err), err); return err; } if (b.mGraphicBuffer == nullptr) { b.mGraphicBuffer = mSlots[b.mSlot].mGraphicBuffer; } if (bufferPointer == NULL) { // not flexible YUV if (b.mFence.get()) { err = mSlots[slot].mGraphicBuffer->lockAsync( GraphicBuffer::USAGE_SW_READ_OFTEN, b.mCrop, &bufferPointer, b.mFence->dup()); } else { err = mSlots[slot].mGraphicBuffer->lock( GraphicBuffer::USAGE_SW_READ_OFTEN, b.mCrop, &bufferPointer); } err = lockBufferItem(b, nativeBuffer); if (err != OK) { CC_LOGE("Unable to lock buffer for CPU reading: %s (%d)", strerror(-err), err); return err; } } size_t lockedIdx = 0; for (; lockedIdx < static_cast<size_t>(mMaxLockedBuffers); lockedIdx++) { if (mAcquiredBuffers[lockedIdx].mSlot == BufferQueue::INVALID_BUFFER_SLOT) { break; } } assert(lockedIdx < mMaxLockedBuffers); // find an unused AcquiredBuffer size_t lockedIdx = findAcquiredBufferLocked(AcquiredBuffer::kUnusedId); ALOG_ASSERT(lockedIdx < mMaxLockedBuffers); AcquiredBuffer& ab = mAcquiredBuffers.editItemAt(lockedIdx); ab.mSlot = slot; ab.mBufferPointer = bufferPointer; ab.mGraphicBuffer = mSlots[slot].mGraphicBuffer; nativeBuffer->data = reinterpret_cast<uint8_t*>(bufferPointer); nativeBuffer->width = mSlots[slot].mGraphicBuffer->getWidth(); nativeBuffer->height = mSlots[slot].mGraphicBuffer->getHeight(); nativeBuffer->format = format; nativeBuffer->flexFormat = flexFormat; nativeBuffer->stride = (ycbcr.y != NULL) ? static_cast<uint32_t>(ycbcr.ystride) : mSlots[slot].mGraphicBuffer->getStride(); nativeBuffer->crop = b.mCrop; nativeBuffer->transform = b.mTransform; nativeBuffer->scalingMode = b.mScalingMode; nativeBuffer->timestamp = b.mTimestamp; nativeBuffer->dataSpace = b.mDataSpace; nativeBuffer->frameNumber = b.mFrameNumber; nativeBuffer->dataCb = reinterpret_cast<uint8_t*>(ycbcr.cb); nativeBuffer->dataCr = reinterpret_cast<uint8_t*>(ycbcr.cr); nativeBuffer->chromaStride = static_cast<uint32_t>(ycbcr.cstride); nativeBuffer->chromaStep = static_cast<uint32_t>(ycbcr.chroma_step); ab.mSlot = b.mSlot; ab.mGraphicBuffer = b.mGraphicBuffer; ab.mLockedBufferId = getLockedBufferId(*nativeBuffer); mCurrentLockedBuffers++; Loading @@ -208,60 +197,34 @@ status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) { status_t CpuConsumer::unlockBuffer(const LockedBuffer &nativeBuffer) { Mutex::Autolock _l(mMutex); size_t lockedIdx = 0; void *bufPtr = reinterpret_cast<void *>(nativeBuffer.data); for (; lockedIdx < static_cast<size_t>(mMaxLockedBuffers); lockedIdx++) { if (bufPtr == mAcquiredBuffers[lockedIdx].mBufferPointer) break; } uintptr_t id = getLockedBufferId(nativeBuffer); size_t lockedIdx = (id != AcquiredBuffer::kUnusedId) ? findAcquiredBufferLocked(id) : mMaxLockedBuffers; if (lockedIdx == mMaxLockedBuffers) { CC_LOGE("%s: Can't find buffer to free", __FUNCTION__); return BAD_VALUE; } return releaseAcquiredBufferLocked(lockedIdx); } status_t CpuConsumer::releaseAcquiredBufferLocked(size_t lockedIdx) { status_t err; int fd = -1; AcquiredBuffer& ab = mAcquiredBuffers.editItemAt(lockedIdx); err = mAcquiredBuffers[lockedIdx].mGraphicBuffer->unlockAsync(&fd); int fenceFd = -1; status_t err = ab.mGraphicBuffer->unlockAsync(&fenceFd); if (err != OK) { CC_LOGE("%s: Unable to unlock graphic buffer %zd", __FUNCTION__, lockedIdx); return err; } int buf = mAcquiredBuffers[lockedIdx].mSlot; if (CC_LIKELY(fd != -1)) { sp<Fence> fence(new Fence(fd)); addReleaseFenceLocked( mAcquiredBuffers[lockedIdx].mSlot, mSlots[buf].mGraphicBuffer, fence); } // release the buffer if it hasn't already been freed by the BufferQueue. // This can happen, for example, when the producer of this buffer // disconnected after this buffer was acquired. if (CC_LIKELY(mAcquiredBuffers[lockedIdx].mGraphicBuffer == mSlots[buf].mGraphicBuffer)) { releaseBufferLocked( buf, mAcquiredBuffers[lockedIdx].mGraphicBuffer, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR); } sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); addReleaseFenceLocked(ab.mSlot, ab.mGraphicBuffer, fence); releaseBufferLocked(ab.mSlot, ab.mGraphicBuffer); AcquiredBuffer &ab = mAcquiredBuffers.editItemAt(lockedIdx); ab.mSlot = BufferQueue::INVALID_BUFFER_SLOT; ab.mBufferPointer = NULL; ab.mGraphicBuffer.clear(); ab.reset(); mCurrentLockedBuffers--; return OK; } void CpuConsumer::freeBufferLocked(int slotIndex) { ConsumerBase::freeBufferLocked(slotIndex); return OK; } } // namespace android libs/gui/GLConsumer.cpp +81 −199 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ #include <hardware/hardware.h> #include <math/mat4.h> #include <gui/BufferItem.h> #include <gui/GLConsumer.h> #include <gui/ISurfaceComposer.h> Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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) { // 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 ); float xform[16]; for (int i = 0; i < 16; i++) { xform[i] = mtxIdentity[i]; } 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(); Loading Loading @@ -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() { Loading Loading @@ -945,45 +943,9 @@ sp<GraphicBuffer> GLConsumer::getCurrentBuffer(int* outSlot) const { 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 { Loading @@ -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(); Loading Loading @@ -1086,61 +1043,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 Loading @@ -1155,28 +1059,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), Loading libs/gui/include/gui/BufferItemConsumer.h +0 −4 Original line number Diff line number Diff line Loading @@ -57,10 +57,6 @@ class BufferItemConsumer: public ConsumerBase ~BufferItemConsumer() override; // set the name of the BufferItemConsumer that will be used to identify it in // log messages. void setName(const String8& name); // setBufferFreedListener sets the listener object that will be notified // when an old buffer is being freed. void setBufferFreedListener(const wp<BufferFreedListener>& listener); Loading Loading
libs/gui/BufferItemConsumer.cpp +0 −10 Original line number Diff line number Diff line Loading @@ -49,16 +49,6 @@ BufferItemConsumer::BufferItemConsumer( BufferItemConsumer::~BufferItemConsumer() {} void BufferItemConsumer::setName(const String8& name) { Mutex::Autolock _l(mMutex); if (mAbandoned) { BI_LOGE("setName: BufferItemConsumer is abandoned!"); return; } mName = name; mConsumer->setConsumerName(name); } void BufferItemConsumer::setBufferFreedListener( const wp<BufferFreedListener>& listener) { Mutex::Autolock _l(mMutex); Loading
libs/gui/ConsumerBase.cpp +54 −0 Original line number Diff line number Diff line Loading @@ -182,6 +182,16 @@ bool ConsumerBase::isAbandoned() { return mAbandoned; } void ConsumerBase::setName(const String8& name) { Mutex::Autolock _l(mMutex); if (mAbandoned) { CB_LOGE("setName: ConsumerBase is abandoned!"); return; } mName = name; mConsumer->setConsumerName(name); } void ConsumerBase::setFrameAvailableListener( const wp<FrameAvailableListener>& listener) { CB_LOGV("setFrameAvailableListener"); Loading Loading @@ -237,6 +247,50 @@ status_t ConsumerBase::setDefaultBufferDataSpace( return mConsumer->setDefaultBufferDataSpace(defaultDataSpace); } status_t ConsumerBase::setConsumerUsageBits(uint64_t usage) { Mutex::Autolock lock(mMutex); if (mAbandoned) { CB_LOGE("setConsumerUsageBits: ConsumerBase is abandoned!"); return NO_INIT; } return mConsumer->setConsumerUsageBits(usage); } status_t ConsumerBase::setTransformHint(uint32_t hint) { Mutex::Autolock lock(mMutex); if (mAbandoned) { CB_LOGE("setTransformHint: ConsumerBase is abandoned!"); return NO_INIT; } return mConsumer->setTransformHint(hint); } status_t ConsumerBase::setMaxAcquiredBufferCount(int maxAcquiredBuffers) { Mutex::Autolock lock(mMutex); if (mAbandoned) { CB_LOGE("setMaxAcquiredBufferCount: ConsumerBase is abandoned!"); return NO_INIT; } return mConsumer->setMaxAcquiredBufferCount(maxAcquiredBuffers); } sp<NativeHandle> ConsumerBase::getSidebandStream() const { Mutex::Autolock _l(mMutex); if (mAbandoned) { CB_LOGE("getSidebandStream: ConsumerBase is abandoned!"); return nullptr; } sp<NativeHandle> stream; status_t err = mConsumer->getSidebandStream(&stream); if (err != NO_ERROR) { CB_LOGE("failed to get sideband stream: %d", err); return nullptr; } return stream; } status_t ConsumerBase::getOccupancyHistory(bool forceFlush, std::vector<OccupancyTracker::Segment>* outHistory) { Mutex::Autolock _l(mMutex); Loading
libs/gui/CpuConsumer.cpp +102 −139 Original line number Diff line number Diff line Loading @@ -18,11 +18,11 @@ #define LOG_TAG "CpuConsumer" //#define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <cutils/compiler.h> #include <utils/Log.h> #include <gui/BufferItem.h> #include <gui/CpuConsumer.h> #include <gui/BufferItem.h> #include <utils/Log.h> #define CC_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__) //#define CC_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__) //#define CC_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__) Loading @@ -44,20 +44,19 @@ CpuConsumer::CpuConsumer(const sp<IGraphicBufferConsumer>& bq, mConsumer->setMaxAcquiredBufferCount(static_cast<int32_t>(maxLockedBuffers)); } CpuConsumer::~CpuConsumer() { // ConsumerBase destructor does all the work. size_t CpuConsumer::findAcquiredBufferLocked(uintptr_t id) const { for (size_t i = 0; i < mMaxLockedBuffers; i++) { const auto& ab = mAcquiredBuffers[i]; // note that this finds AcquiredBuffer::kUnusedId as well if (ab.mLockedBufferId == id) { return i; } void CpuConsumer::setName(const String8& name) { Mutex::Autolock _l(mMutex); if (mAbandoned) { CC_LOGE("setName: CpuConsumer is abandoned!"); return; } mName = name; mConsumer->setConsumerName(name); return mMaxLockedBuffers; // an invalid index } static uintptr_t getLockedBufferId(const CpuConsumer::LockedBuffer& buffer) { return reinterpret_cast<uintptr_t>(buffer.data); } static bool isPossiblyYUV(PixelFormat format) { Loading Loading @@ -88,10 +87,74 @@ static bool isPossiblyYUV(PixelFormat format) { } } status_t CpuConsumer::lockBufferItem(const BufferItem& item, LockedBuffer* outBuffer) const { android_ycbcr ycbcr = android_ycbcr(); PixelFormat format = item.mGraphicBuffer->getPixelFormat(); PixelFormat flexFormat = format; if (isPossiblyYUV(format)) { int fenceFd = item.mFence.get() ? item.mFence->dup() : -1; status_t err = item.mGraphicBuffer->lockAsyncYCbCr(GraphicBuffer::USAGE_SW_READ_OFTEN, item.mCrop, &ycbcr, fenceFd); if (err == OK) { flexFormat = HAL_PIXEL_FORMAT_YCbCr_420_888; if (format != HAL_PIXEL_FORMAT_YCbCr_420_888) { CC_LOGV("locking buffer of format %#x as flex YUV", format); } } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) { CC_LOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)", strerror(-err), err); return err; } } if (ycbcr.y != nullptr) { outBuffer->data = reinterpret_cast<uint8_t*>(ycbcr.y); outBuffer->stride = static_cast<uint32_t>(ycbcr.ystride); outBuffer->dataCb = reinterpret_cast<uint8_t*>(ycbcr.cb); outBuffer->dataCr = reinterpret_cast<uint8_t*>(ycbcr.cr); outBuffer->chromaStride = static_cast<uint32_t>(ycbcr.cstride); outBuffer->chromaStep = static_cast<uint32_t>(ycbcr.chroma_step); } else { // not flexible YUV; try lockAsync void* bufferPointer = nullptr; int fenceFd = item.mFence.get() ? item.mFence->dup() : -1; status_t err = item.mGraphicBuffer->lockAsync(GraphicBuffer::USAGE_SW_READ_OFTEN, item.mCrop, &bufferPointer, fenceFd); if (err != OK) { CC_LOGE("Unable to lock buffer for CPU reading: %s (%d)", strerror(-err), err); return err; } outBuffer->data = reinterpret_cast<uint8_t*>(bufferPointer); outBuffer->stride = item.mGraphicBuffer->getStride(); outBuffer->dataCb = nullptr; outBuffer->dataCr = nullptr; outBuffer->chromaStride = 0; outBuffer->chromaStep = 0; } outBuffer->width = item.mGraphicBuffer->getWidth(); outBuffer->height = item.mGraphicBuffer->getHeight(); outBuffer->format = format; outBuffer->flexFormat = flexFormat; outBuffer->crop = item.mCrop; outBuffer->transform = item.mTransform; outBuffer->scalingMode = item.mScalingMode; outBuffer->timestamp = item.mTimestamp; outBuffer->dataSpace = item.mDataSpace; outBuffer->frameNumber = item.mFrameNumber; return OK; } status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) { status_t err; if (!nativeBuffer) return BAD_VALUE; Mutex::Autolock _l(mMutex); if (mCurrentLockedBuffers == mMaxLockedBuffers) { CC_LOGW("Max buffers have been locked (%zd), cannot lock anymore.", mMaxLockedBuffers); Loading @@ -99,9 +162,6 @@ status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) { } BufferItem b; Mutex::Autolock _l(mMutex); err = acquireBufferLocked(&b, 0); if (err != OK) { if (err == BufferQueue::NO_BUFFER_AVAILABLE) { Loading @@ -112,94 +172,23 @@ status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) { } } int slot = b.mSlot; void *bufferPointer = NULL; android_ycbcr ycbcr = android_ycbcr(); PixelFormat format = mSlots[slot].mGraphicBuffer->getPixelFormat(); PixelFormat flexFormat = format; if (isPossiblyYUV(format)) { if (b.mFence.get()) { err = mSlots[slot].mGraphicBuffer->lockAsyncYCbCr( GraphicBuffer::USAGE_SW_READ_OFTEN, b.mCrop, &ycbcr, b.mFence->dup()); } else { err = mSlots[slot].mGraphicBuffer->lockYCbCr( GraphicBuffer::USAGE_SW_READ_OFTEN, b.mCrop, &ycbcr); } if (err == OK) { bufferPointer = ycbcr.y; flexFormat = HAL_PIXEL_FORMAT_YCbCr_420_888; if (format != HAL_PIXEL_FORMAT_YCbCr_420_888) { CC_LOGV("locking buffer of format %#x as flex YUV", format); } } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) { CC_LOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)", strerror(-err), err); return err; } if (b.mGraphicBuffer == nullptr) { b.mGraphicBuffer = mSlots[b.mSlot].mGraphicBuffer; } if (bufferPointer == NULL) { // not flexible YUV if (b.mFence.get()) { err = mSlots[slot].mGraphicBuffer->lockAsync( GraphicBuffer::USAGE_SW_READ_OFTEN, b.mCrop, &bufferPointer, b.mFence->dup()); } else { err = mSlots[slot].mGraphicBuffer->lock( GraphicBuffer::USAGE_SW_READ_OFTEN, b.mCrop, &bufferPointer); } err = lockBufferItem(b, nativeBuffer); if (err != OK) { CC_LOGE("Unable to lock buffer for CPU reading: %s (%d)", strerror(-err), err); return err; } } size_t lockedIdx = 0; for (; lockedIdx < static_cast<size_t>(mMaxLockedBuffers); lockedIdx++) { if (mAcquiredBuffers[lockedIdx].mSlot == BufferQueue::INVALID_BUFFER_SLOT) { break; } } assert(lockedIdx < mMaxLockedBuffers); // find an unused AcquiredBuffer size_t lockedIdx = findAcquiredBufferLocked(AcquiredBuffer::kUnusedId); ALOG_ASSERT(lockedIdx < mMaxLockedBuffers); AcquiredBuffer& ab = mAcquiredBuffers.editItemAt(lockedIdx); ab.mSlot = slot; ab.mBufferPointer = bufferPointer; ab.mGraphicBuffer = mSlots[slot].mGraphicBuffer; nativeBuffer->data = reinterpret_cast<uint8_t*>(bufferPointer); nativeBuffer->width = mSlots[slot].mGraphicBuffer->getWidth(); nativeBuffer->height = mSlots[slot].mGraphicBuffer->getHeight(); nativeBuffer->format = format; nativeBuffer->flexFormat = flexFormat; nativeBuffer->stride = (ycbcr.y != NULL) ? static_cast<uint32_t>(ycbcr.ystride) : mSlots[slot].mGraphicBuffer->getStride(); nativeBuffer->crop = b.mCrop; nativeBuffer->transform = b.mTransform; nativeBuffer->scalingMode = b.mScalingMode; nativeBuffer->timestamp = b.mTimestamp; nativeBuffer->dataSpace = b.mDataSpace; nativeBuffer->frameNumber = b.mFrameNumber; nativeBuffer->dataCb = reinterpret_cast<uint8_t*>(ycbcr.cb); nativeBuffer->dataCr = reinterpret_cast<uint8_t*>(ycbcr.cr); nativeBuffer->chromaStride = static_cast<uint32_t>(ycbcr.cstride); nativeBuffer->chromaStep = static_cast<uint32_t>(ycbcr.chroma_step); ab.mSlot = b.mSlot; ab.mGraphicBuffer = b.mGraphicBuffer; ab.mLockedBufferId = getLockedBufferId(*nativeBuffer); mCurrentLockedBuffers++; Loading @@ -208,60 +197,34 @@ status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) { status_t CpuConsumer::unlockBuffer(const LockedBuffer &nativeBuffer) { Mutex::Autolock _l(mMutex); size_t lockedIdx = 0; void *bufPtr = reinterpret_cast<void *>(nativeBuffer.data); for (; lockedIdx < static_cast<size_t>(mMaxLockedBuffers); lockedIdx++) { if (bufPtr == mAcquiredBuffers[lockedIdx].mBufferPointer) break; } uintptr_t id = getLockedBufferId(nativeBuffer); size_t lockedIdx = (id != AcquiredBuffer::kUnusedId) ? findAcquiredBufferLocked(id) : mMaxLockedBuffers; if (lockedIdx == mMaxLockedBuffers) { CC_LOGE("%s: Can't find buffer to free", __FUNCTION__); return BAD_VALUE; } return releaseAcquiredBufferLocked(lockedIdx); } status_t CpuConsumer::releaseAcquiredBufferLocked(size_t lockedIdx) { status_t err; int fd = -1; AcquiredBuffer& ab = mAcquiredBuffers.editItemAt(lockedIdx); err = mAcquiredBuffers[lockedIdx].mGraphicBuffer->unlockAsync(&fd); int fenceFd = -1; status_t err = ab.mGraphicBuffer->unlockAsync(&fenceFd); if (err != OK) { CC_LOGE("%s: Unable to unlock graphic buffer %zd", __FUNCTION__, lockedIdx); return err; } int buf = mAcquiredBuffers[lockedIdx].mSlot; if (CC_LIKELY(fd != -1)) { sp<Fence> fence(new Fence(fd)); addReleaseFenceLocked( mAcquiredBuffers[lockedIdx].mSlot, mSlots[buf].mGraphicBuffer, fence); } // release the buffer if it hasn't already been freed by the BufferQueue. // This can happen, for example, when the producer of this buffer // disconnected after this buffer was acquired. if (CC_LIKELY(mAcquiredBuffers[lockedIdx].mGraphicBuffer == mSlots[buf].mGraphicBuffer)) { releaseBufferLocked( buf, mAcquiredBuffers[lockedIdx].mGraphicBuffer, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR); } sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); addReleaseFenceLocked(ab.mSlot, ab.mGraphicBuffer, fence); releaseBufferLocked(ab.mSlot, ab.mGraphicBuffer); AcquiredBuffer &ab = mAcquiredBuffers.editItemAt(lockedIdx); ab.mSlot = BufferQueue::INVALID_BUFFER_SLOT; ab.mBufferPointer = NULL; ab.mGraphicBuffer.clear(); ab.reset(); mCurrentLockedBuffers--; return OK; } void CpuConsumer::freeBufferLocked(int slotIndex) { ConsumerBase::freeBufferLocked(slotIndex); return OK; } } // namespace android
libs/gui/GLConsumer.cpp +81 −199 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ #include <hardware/hardware.h> #include <math/mat4.h> #include <gui/BufferItem.h> #include <gui/GLConsumer.h> #include <gui/ISurfaceComposer.h> Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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) { // 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 ); float xform[16]; for (int i = 0; i < 16; i++) { xform[i] = mtxIdentity[i]; } 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(); Loading Loading @@ -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() { Loading Loading @@ -945,45 +943,9 @@ sp<GraphicBuffer> GLConsumer::getCurrentBuffer(int* outSlot) const { 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 { Loading @@ -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(); Loading Loading @@ -1086,61 +1043,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 Loading @@ -1155,28 +1059,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), Loading
libs/gui/include/gui/BufferItemConsumer.h +0 −4 Original line number Diff line number Diff line Loading @@ -57,10 +57,6 @@ class BufferItemConsumer: public ConsumerBase ~BufferItemConsumer() override; // set the name of the BufferItemConsumer that will be used to identify it in // log messages. void setName(const String8& name); // setBufferFreedListener sets the listener object that will be notified // when an old buffer is being freed. void setBufferFreedListener(const wp<BufferFreedListener>& listener); Loading