Loading libs/hwui/surfacetexture/ImageConsumer.cpp +54 −16 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "renderthread/RenderThread.h" #include "renderthread/VulkanManager.h" #include "utils/Color.h" #include <GrAHardwareBufferUtils.h> // Macro for including the SurfaceTexture name in log messages #define IMG_LOGE(x, ...) ALOGE("[%s] " x, st.mName.string(), ##__VA_ARGS__) Loading @@ -30,31 +31,67 @@ namespace android { void ImageConsumer::onFreeBufferLocked(int slotIndex) { mImageSlots[slotIndex].mImage.reset(); mImageSlots[slotIndex].clear(); } void ImageConsumer::onAcquireBufferLocked(BufferItem* item) { // If item->mGraphicBuffer is not null, this buffer has not been acquired // before, so any prior SkImage is created with a stale buffer. This resets the stale SkImage. if (item->mGraphicBuffer != nullptr) { mImageSlots[item->mSlot].mImage.reset(); mImageSlots[item->mSlot].clear(); } } void ImageConsumer::onReleaseBufferLocked(int buf) { mImageSlots[buf].mEglFence = EGL_NO_SYNC_KHR; mImageSlots[buf].eglFence() = EGL_NO_SYNC_KHR; } void ImageConsumer::ImageSlot::createIfNeeded(sp<GraphicBuffer> graphicBuffer, android_dataspace dataspace, bool forceCreate) { android_dataspace dataspace, bool forceCreate, GrContext* context) { if (!mImage.get() || dataspace != mDataspace || forceCreate) { mImage = graphicBuffer.get() ? SkImage::MakeFromAHardwareBuffer( if (!graphicBuffer.get()) { clear(); return; } if (!mBackendTexture.isValid()) { clear(); bool createProtectedImage = 0 != (graphicBuffer->getUsage() & GraphicBuffer::USAGE_PROTECTED); GrBackendFormat backendFormat = GrAHardwareBufferUtils::GetBackendFormat( context, reinterpret_cast<AHardwareBuffer*>(graphicBuffer.get()), kPremul_SkAlphaType, uirenderer::DataSpaceToColorSpace(dataspace)) : nullptr; graphicBuffer->getPixelFormat(), false); mBackendTexture = GrAHardwareBufferUtils::MakeBackendTexture( context, reinterpret_cast<AHardwareBuffer*>(graphicBuffer.get()), graphicBuffer->getWidth(), graphicBuffer->getHeight(), &mDeleteProc, &mDeleteCtx, createProtectedImage, backendFormat, false); } mDataspace = dataspace; SkColorType colorType = GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat( graphicBuffer->getPixelFormat()); mImage = SkImage::MakeFromTexture(context, mBackendTexture, kTopLeft_GrSurfaceOrigin, colorType, kPremul_SkAlphaType, uirenderer::DataSpaceToColorSpace(dataspace)); } } void ImageConsumer::ImageSlot::clear() { mImage.reset(); if (mBackendTexture.isValid()) { mDeleteProc(mDeleteCtx); mBackendTexture = {}; } } Loading @@ -71,8 +108,8 @@ sk_sp<SkImage> ImageConsumer::dequeueImage(bool* queueEmpty, SurfaceTexture& st, if (slot != BufferItem::INVALID_BUFFER_SLOT) { *queueEmpty = true; mImageSlots[slot].createIfNeeded(st.mSlots[slot].mGraphicBuffer, st.mCurrentDataSpace, false); return mImageSlots[slot].mImage; st.mCurrentDataSpace, false, renderState.getRenderThread().getGrContext()); return mImageSlots[slot].getImage(); } } return nullptr; Loading Loading @@ -104,7 +141,7 @@ sk_sp<SkImage> ImageConsumer::dequeueImage(bool* queueEmpty, SurfaceTexture& st, uirenderer::RenderPipelineType::SkiaGL) { auto& eglManager = renderState.getRenderThread().eglManager(); display = eglManager.eglDisplay(); err = eglManager.createReleaseFence(st.mUseFenceSync, &mImageSlots[slot].mEglFence, err = eglManager.createReleaseFence(st.mUseFenceSync, &mImageSlots[slot].eglFence(), releaseFence); } else { err = renderState.getRenderThread().vulkanManager().createReleaseFence(releaseFence); Loading @@ -129,7 +166,7 @@ sk_sp<SkImage> ImageConsumer::dequeueImage(bool* queueEmpty, SurfaceTexture& st, // Finally release the old buffer. status_t status = st.releaseBufferLocked( st.mCurrentTexture, st.mSlots[st.mCurrentTexture].mGraphicBuffer, display, mImageSlots[st.mCurrentTexture].mEglFence); mImageSlots[st.mCurrentTexture].eglFence()); if (status < NO_ERROR) { IMG_LOGE("dequeueImage: failed to release buffer: %s (%d)", strerror(-status), status); err = status; Loading @@ -150,8 +187,9 @@ sk_sp<SkImage> ImageConsumer::dequeueImage(bool* queueEmpty, SurfaceTexture& st, st.computeCurrentTransformMatrixLocked(); *queueEmpty = false; mImageSlots[slot].createIfNeeded(st.mSlots[slot].mGraphicBuffer, item.mDataSpace, true); return mImageSlots[slot].mImage; mImageSlots[slot].createIfNeeded(st.mSlots[slot].mGraphicBuffer, item.mDataSpace, true, renderState.getRenderThread().getGrContext()); return mImageSlots[slot].getImage(); } } /* namespace android */ libs/hwui/surfacetexture/ImageConsumer.h +24 −3 Original line number Diff line number Diff line Loading @@ -25,6 +25,12 @@ #include <cutils/compiler.h> #include <gui/BufferItem.h> #include <system/graphics.h> #include <GrBackendSurface.h> namespace GrAHardwareBufferUtils { typedef void* DeleteImageCtx; typedef void (*DeleteImageProc)(DeleteImageCtx); } namespace android { Loading Loading @@ -67,9 +73,21 @@ private: * ImageSlot contains the information and object references that * ImageConsumer maintains about a BufferQueue buffer slot. */ struct ImageSlot { class ImageSlot { public: ImageSlot() : mDataspace(HAL_DATASPACE_UNKNOWN), mEglFence(EGL_NO_SYNC_KHR) {} ~ImageSlot() { clear(); } void createIfNeeded(sp<GraphicBuffer> graphicBuffer, android_dataspace dataspace, bool forceCreate, GrContext* context); void clear(); inline EGLSyncKHR& eglFence() { return mEglFence; } inline sk_sp<SkImage> getImage() { return mImage; } private: // mImage is the SkImage created from mGraphicBuffer. sk_sp<SkImage> mImage; Loading @@ -82,8 +100,11 @@ private: */ EGLSyncKHR mEglFence; void createIfNeeded(sp<GraphicBuffer> graphicBuffer, android_dataspace dataspace, bool forceCreate); GrBackendTexture mBackendTexture; GrAHardwareBufferUtils::DeleteImageProc mDeleteProc; GrAHardwareBufferUtils::DeleteImageCtx mDeleteCtx; }; /** Loading libs/hwui/surfacetexture/SurfaceTexture.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "Matrix.h" #include "SurfaceTexture.h" #include "ImageConsumer.h" namespace android { Loading Loading @@ -150,7 +151,7 @@ status_t SurfaceTexture::releaseBufferLocked(int buf, sp<GraphicBuffer> graphicB // buffer has reallocated the original buffer slot after this buffer // was acquired. status_t err = ConsumerBase::releaseBufferLocked(buf, graphicBuffer, display, eglFence); // We could be releasing an EGL buffer, even if not currently attached to a GL context. // We could be releasing an EGL/Vulkan buffer, even if not currently attached to a GL context. mImageConsumer.onReleaseBufferLocked(buf); mEGLConsumer.onReleaseBufferLocked(buf); return err; Loading Loading @@ -235,6 +236,10 @@ void SurfaceTexture::detachFromView() { if (mOpMode == OpMode::attachedToView) { mOpMode = OpMode::detached; // Free all EglImage and VkImage before the context is destroyed. for (int i=0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; i++) { mImageConsumer.onFreeBufferLocked(i); } } else { SFT_LOGE("detachFromView: not attached to View"); } Loading Loading
libs/hwui/surfacetexture/ImageConsumer.cpp +54 −16 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "renderthread/RenderThread.h" #include "renderthread/VulkanManager.h" #include "utils/Color.h" #include <GrAHardwareBufferUtils.h> // Macro for including the SurfaceTexture name in log messages #define IMG_LOGE(x, ...) ALOGE("[%s] " x, st.mName.string(), ##__VA_ARGS__) Loading @@ -30,31 +31,67 @@ namespace android { void ImageConsumer::onFreeBufferLocked(int slotIndex) { mImageSlots[slotIndex].mImage.reset(); mImageSlots[slotIndex].clear(); } void ImageConsumer::onAcquireBufferLocked(BufferItem* item) { // If item->mGraphicBuffer is not null, this buffer has not been acquired // before, so any prior SkImage is created with a stale buffer. This resets the stale SkImage. if (item->mGraphicBuffer != nullptr) { mImageSlots[item->mSlot].mImage.reset(); mImageSlots[item->mSlot].clear(); } } void ImageConsumer::onReleaseBufferLocked(int buf) { mImageSlots[buf].mEglFence = EGL_NO_SYNC_KHR; mImageSlots[buf].eglFence() = EGL_NO_SYNC_KHR; } void ImageConsumer::ImageSlot::createIfNeeded(sp<GraphicBuffer> graphicBuffer, android_dataspace dataspace, bool forceCreate) { android_dataspace dataspace, bool forceCreate, GrContext* context) { if (!mImage.get() || dataspace != mDataspace || forceCreate) { mImage = graphicBuffer.get() ? SkImage::MakeFromAHardwareBuffer( if (!graphicBuffer.get()) { clear(); return; } if (!mBackendTexture.isValid()) { clear(); bool createProtectedImage = 0 != (graphicBuffer->getUsage() & GraphicBuffer::USAGE_PROTECTED); GrBackendFormat backendFormat = GrAHardwareBufferUtils::GetBackendFormat( context, reinterpret_cast<AHardwareBuffer*>(graphicBuffer.get()), kPremul_SkAlphaType, uirenderer::DataSpaceToColorSpace(dataspace)) : nullptr; graphicBuffer->getPixelFormat(), false); mBackendTexture = GrAHardwareBufferUtils::MakeBackendTexture( context, reinterpret_cast<AHardwareBuffer*>(graphicBuffer.get()), graphicBuffer->getWidth(), graphicBuffer->getHeight(), &mDeleteProc, &mDeleteCtx, createProtectedImage, backendFormat, false); } mDataspace = dataspace; SkColorType colorType = GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat( graphicBuffer->getPixelFormat()); mImage = SkImage::MakeFromTexture(context, mBackendTexture, kTopLeft_GrSurfaceOrigin, colorType, kPremul_SkAlphaType, uirenderer::DataSpaceToColorSpace(dataspace)); } } void ImageConsumer::ImageSlot::clear() { mImage.reset(); if (mBackendTexture.isValid()) { mDeleteProc(mDeleteCtx); mBackendTexture = {}; } } Loading @@ -71,8 +108,8 @@ sk_sp<SkImage> ImageConsumer::dequeueImage(bool* queueEmpty, SurfaceTexture& st, if (slot != BufferItem::INVALID_BUFFER_SLOT) { *queueEmpty = true; mImageSlots[slot].createIfNeeded(st.mSlots[slot].mGraphicBuffer, st.mCurrentDataSpace, false); return mImageSlots[slot].mImage; st.mCurrentDataSpace, false, renderState.getRenderThread().getGrContext()); return mImageSlots[slot].getImage(); } } return nullptr; Loading Loading @@ -104,7 +141,7 @@ sk_sp<SkImage> ImageConsumer::dequeueImage(bool* queueEmpty, SurfaceTexture& st, uirenderer::RenderPipelineType::SkiaGL) { auto& eglManager = renderState.getRenderThread().eglManager(); display = eglManager.eglDisplay(); err = eglManager.createReleaseFence(st.mUseFenceSync, &mImageSlots[slot].mEglFence, err = eglManager.createReleaseFence(st.mUseFenceSync, &mImageSlots[slot].eglFence(), releaseFence); } else { err = renderState.getRenderThread().vulkanManager().createReleaseFence(releaseFence); Loading @@ -129,7 +166,7 @@ sk_sp<SkImage> ImageConsumer::dequeueImage(bool* queueEmpty, SurfaceTexture& st, // Finally release the old buffer. status_t status = st.releaseBufferLocked( st.mCurrentTexture, st.mSlots[st.mCurrentTexture].mGraphicBuffer, display, mImageSlots[st.mCurrentTexture].mEglFence); mImageSlots[st.mCurrentTexture].eglFence()); if (status < NO_ERROR) { IMG_LOGE("dequeueImage: failed to release buffer: %s (%d)", strerror(-status), status); err = status; Loading @@ -150,8 +187,9 @@ sk_sp<SkImage> ImageConsumer::dequeueImage(bool* queueEmpty, SurfaceTexture& st, st.computeCurrentTransformMatrixLocked(); *queueEmpty = false; mImageSlots[slot].createIfNeeded(st.mSlots[slot].mGraphicBuffer, item.mDataSpace, true); return mImageSlots[slot].mImage; mImageSlots[slot].createIfNeeded(st.mSlots[slot].mGraphicBuffer, item.mDataSpace, true, renderState.getRenderThread().getGrContext()); return mImageSlots[slot].getImage(); } } /* namespace android */
libs/hwui/surfacetexture/ImageConsumer.h +24 −3 Original line number Diff line number Diff line Loading @@ -25,6 +25,12 @@ #include <cutils/compiler.h> #include <gui/BufferItem.h> #include <system/graphics.h> #include <GrBackendSurface.h> namespace GrAHardwareBufferUtils { typedef void* DeleteImageCtx; typedef void (*DeleteImageProc)(DeleteImageCtx); } namespace android { Loading Loading @@ -67,9 +73,21 @@ private: * ImageSlot contains the information and object references that * ImageConsumer maintains about a BufferQueue buffer slot. */ struct ImageSlot { class ImageSlot { public: ImageSlot() : mDataspace(HAL_DATASPACE_UNKNOWN), mEglFence(EGL_NO_SYNC_KHR) {} ~ImageSlot() { clear(); } void createIfNeeded(sp<GraphicBuffer> graphicBuffer, android_dataspace dataspace, bool forceCreate, GrContext* context); void clear(); inline EGLSyncKHR& eglFence() { return mEglFence; } inline sk_sp<SkImage> getImage() { return mImage; } private: // mImage is the SkImage created from mGraphicBuffer. sk_sp<SkImage> mImage; Loading @@ -82,8 +100,11 @@ private: */ EGLSyncKHR mEglFence; void createIfNeeded(sp<GraphicBuffer> graphicBuffer, android_dataspace dataspace, bool forceCreate); GrBackendTexture mBackendTexture; GrAHardwareBufferUtils::DeleteImageProc mDeleteProc; GrAHardwareBufferUtils::DeleteImageCtx mDeleteCtx; }; /** Loading
libs/hwui/surfacetexture/SurfaceTexture.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "Matrix.h" #include "SurfaceTexture.h" #include "ImageConsumer.h" namespace android { Loading Loading @@ -150,7 +151,7 @@ status_t SurfaceTexture::releaseBufferLocked(int buf, sp<GraphicBuffer> graphicB // buffer has reallocated the original buffer slot after this buffer // was acquired. status_t err = ConsumerBase::releaseBufferLocked(buf, graphicBuffer, display, eglFence); // We could be releasing an EGL buffer, even if not currently attached to a GL context. // We could be releasing an EGL/Vulkan buffer, even if not currently attached to a GL context. mImageConsumer.onReleaseBufferLocked(buf); mEGLConsumer.onReleaseBufferLocked(buf); return err; Loading Loading @@ -235,6 +236,10 @@ void SurfaceTexture::detachFromView() { if (mOpMode == OpMode::attachedToView) { mOpMode = OpMode::detached; // Free all EglImage and VkImage before the context is destroyed. for (int i=0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; i++) { mImageConsumer.onFreeBufferLocked(i); } } else { SFT_LOGE("detachFromView: not attached to View"); } Loading