From 9af948d4688cd7e3f3e68227c03d0431bca76663 Mon Sep 17 00:00:00 2001 From: Greg Daniel Date: Mon, 27 Aug 2018 09:53:51 -0400 Subject: [PATCH] Do some refactoring of GrAHardwareBufferImageGenerator. This is just some pre-work to split out from the change to make the GrAHardwareBufferImageGenerator use lazy proxies. Bug: skia: Change-Id: I655d0c20070cff391d2bb9487b7c73253493cf71 Reviewed-on: https://skia-review.googlesource.com/148060 Reviewed-by: Brian Osman Commit-Queue: Greg Daniel --- src/gpu/GrAHardwareBufferImageGenerator.cpp | 209 ++++++++++++-------- src/gpu/GrAHardwareBufferImageGenerator.h | 7 +- 2 files changed, 132 insertions(+), 84 deletions(-) diff --git a/src/gpu/GrAHardwareBufferImageGenerator.cpp b/src/gpu/GrAHardwareBufferImageGenerator.cpp index 2b38a60e93..e69467c656 100644 --- a/src/gpu/GrAHardwareBufferImageGenerator.cpp +++ b/src/gpu/GrAHardwareBufferImageGenerator.cpp @@ -29,19 +29,6 @@ #include #include -class BufferCleanupHelper { -public: - BufferCleanupHelper(EGLImageKHR image, EGLDisplay display) - : fImage(image) - , fDisplay(display) { } - ~BufferCleanupHelper() { - eglDestroyImageKHR(fDisplay, fImage); - } -private: - EGLImageKHR fImage; - EGLDisplay fDisplay; -}; - std::unique_ptr GrAHardwareBufferImageGenerator::Make( AHardwareBuffer* graphicBuffer, SkAlphaType alphaType, sk_sp colorSpace) { AHardwareBuffer_Desc bufferDesc; @@ -88,11 +75,6 @@ void GrAHardwareBufferImageGenerator::clear() { } } -void GrAHardwareBufferImageGenerator::deleteImageTexture(void* context) { - BufferCleanupHelper* cleanupHelper = static_cast(context); - delete cleanupHelper; -} - /////////////////////////////////////////////////////////////////////////////////////////////////// sk_sp GrAHardwareBufferImageGenerator::onGenerateTexture( @@ -104,7 +86,7 @@ sk_sp GrAHardwareBufferImageGenerator::onGenerateTexture( bool makingASubset = true; if (0 == origin.fX && 0 == origin.fY && - info.width() == getInfo().width() && info.height() == getInfo().height()) { + info.width() == this->getInfo().width() && info.height() == this->getInfo().height()) { makingASubset = false; if (!willNeedMipMaps || GrMipMapped::kYes == proxy->mipMapped()) { // If the caller wants the full texture and we have the correct mip support, we're done @@ -142,6 +124,104 @@ sk_sp GrAHardwareBufferImageGenerator::onGenerateTexture( return texProxy; } +class BufferCleanupHelper { +public: + BufferCleanupHelper(EGLImageKHR image, EGLDisplay display) + : fImage(image) + , fDisplay(display) { } + ~BufferCleanupHelper() { + eglDestroyImageKHR(fDisplay, fImage); + } +private: + EGLImageKHR fImage; + EGLDisplay fDisplay; +}; + + +void GrAHardwareBufferImageGenerator::DeleteEGLImage(void* context) { + BufferCleanupHelper* cleanupHelper = static_cast(context); + delete cleanupHelper; +} + +static GrBackendTexture make_gl_backend_texture( + GrContext* context, AHardwareBuffer* hardwareBuffer, + int width, int height, + GrAHardwareBufferImageGenerator::DeleteImageProc* deleteProc, + GrAHardwareBufferImageGenerator::DeleteImageCtx* deleteCtx) { + while (GL_NO_ERROR != glGetError()) {} //clear GL errors + + EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(hardwareBuffer); + EGLint attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, + EGL_NONE }; + EGLDisplay display = eglGetCurrentDisplay(); + EGLImageKHR image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, + clientBuffer, attribs); + if (EGL_NO_IMAGE_KHR == image) { + SkDebugf("Could not create EGL image, err = (%#x)", (int) eglGetError() ); + return GrBackendTexture(); + } + + GrGLuint texID; + glGenTextures(1, &texID); + if (!texID) { + eglDestroyImageKHR(display, image); + return GrBackendTexture(); + } + glBindTexture(GL_TEXTURE_EXTERNAL_OES, texID); + GLenum status = GL_NO_ERROR; + if ((status = glGetError()) != GL_NO_ERROR) { + SkDebugf("glBindTexture failed (%#x)", (int) status); + glDeleteTextures(1, &texID); + eglDestroyImageKHR(display, image); + return GrBackendTexture(); + } + glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image); + if ((status = glGetError()) != GL_NO_ERROR) { + SkDebugf("glEGLImageTargetTexture2DOES failed (%#x)", (int) status); + glDeleteTextures(1, &texID); + eglDestroyImageKHR(display, image); + return GrBackendTexture(); + } + context->resetContext(kTextureBinding_GrGLBackendState); + + GrGLTextureInfo textureInfo; + textureInfo.fTarget = GL_TEXTURE_EXTERNAL_OES; + textureInfo.fID = texID; + + *deleteProc = GrAHardwareBufferImageGenerator::DeleteEGLImage; + *deleteCtx = new BufferCleanupHelper(image, display); + + return GrBackendTexture(width, height, GrMipMapped::kNo, textureInfo); +} + +static GrBackendTexture make_backend_texture( + GrContext* context, AHardwareBuffer* hardwareBuffer, + int width, int height, + GrAHardwareBufferImageGenerator::DeleteImageProc* deleteProc, + GrAHardwareBufferImageGenerator::DeleteImageCtx* deleteCtx) { + if (context->abandoned() || kOpenGL_GrBackend != context->contextPriv().getBackend()) { + // Check if GrContext is not abandoned and the backend is GL. + return GrBackendTexture(); + } + return make_gl_backend_texture(context, hardwareBuffer, width, height, deleteProc, deleteCtx); +} + +static void free_backend_texture(GrBackendTexture* backendTexture) { + SkASSERT(backendTexture && backendTexture->isValid()); + + switch (backendTexture->backend()) { + case kOpenGL_GrBackend: { + GrGLTextureInfo texInfo; + SkAssertResult(backendTexture->getGLTextureInfo(&texInfo)); + glDeleteTextures(1, &texInfo.fID); + return; + } + case kVulkan_GrBackend: // fall through + default: + return; + } +} + sk_sp GrAHardwareBufferImageGenerator::makeProxy(GrContext* context) { if (context->abandoned() || kOpenGL_GrBackend != context->contextPriv().getBackend()) { // Check if GrContext is not abandoned and the backend is GL. @@ -156,81 +236,46 @@ sk_sp GrAHardwareBufferImageGenerator::makeProxy(GrContext* cont kTopLeft_GrSurfaceOrigin); } - while (GL_NO_ERROR != glGetError()) {} //clear GL errors - - EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(fGraphicBuffer); - EGLint attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, - EGL_NONE }; - EGLDisplay display = eglGetCurrentDisplay(); - EGLImageKHR image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, - clientBuffer, attribs); - if (EGL_NO_IMAGE_KHR == image) { - SkDebugf("Could not create EGL image, err = (%#x)", (int) eglGetError() ); - return nullptr; - } - GrGLuint texID; - glGenTextures(1, &texID); - if (!texID) { - eglDestroyImageKHR(display, image); - return nullptr; - } - glBindTexture(GL_TEXTURE_EXTERNAL_OES, texID); - GLenum status = GL_NO_ERROR; - if ((status = glGetError()) != GL_NO_ERROR) { - SkDebugf("glBindTexture failed (%#x)", (int) status); - glDeleteTextures(1, &texID); - eglDestroyImageKHR(display, image); - return nullptr; - } - glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image); - if ((status = glGetError()) != GL_NO_ERROR) { - SkDebugf("glEGLImageTargetTexture2DOES failed (%#x)", (int) status); - glDeleteTextures(1, &texID); - eglDestroyImageKHR(display, image); - return nullptr; - } - context->resetContext(kTextureBinding_GrGLBackendState); - - GrGLTextureInfo textureInfo; - textureInfo.fTarget = GL_TEXTURE_EXTERNAL_OES; - textureInfo.fID = texID; - GrPixelConfig pixelConfig; - switch (getInfo().colorType()) { - case kRGBA_8888_SkColorType: - pixelConfig = kRGBA_8888_GrPixelConfig; - break; - case kRGBA_F16_SkColorType: - pixelConfig = kRGBA_half_GrPixelConfig; - break; - case kRGB_565_SkColorType: - pixelConfig = kRGB_565_GrPixelConfig; - break; - default: - glDeleteTextures(1, &texID); - eglDestroyImageKHR(display, image); - return nullptr; + switch (this->getInfo().colorType()) { + case kRGBA_8888_SkColorType: + pixelConfig = kRGBA_8888_GrPixelConfig; + break; + case kRGBA_F16_SkColorType: + pixelConfig = kRGBA_half_GrPixelConfig; + break; + case kRGB_565_SkColorType: + pixelConfig = kRGB_565_GrPixelConfig; + break; + default: + return nullptr; } - GrBackendTexture backendTex(getInfo().width(), getInfo().height(), GrMipMapped::kNo, - textureInfo); - if (backendTex.width() <= 0 || backendTex.height() <= 0) { - glDeleteTextures(1, &texID); - eglDestroyImageKHR(display, image); + DeleteImageProc deleteImageProc = nullptr; + DeleteImageCtx deleteImageCtx = nullptr; + + GrBackendTexture backendTex = make_backend_texture(context, fGraphicBuffer, + this->getInfo().width(), + this->getInfo().height(), + &deleteImageProc, + &deleteImageCtx); + + if (!backendTex.isValid()) { return nullptr; } + SkASSERT(deleteImageProc && deleteImageCtx); backendTex.fConfig = pixelConfig; sk_sp tex = context->contextPriv().resourceProvider()->wrapBackendTexture( backendTex, kAdopt_GrWrapOwnership); if (!tex) { - glDeleteTextures(1, &texID); - eglDestroyImageKHR(display, image); + free_backend_texture(&backendTex); + deleteImageProc(deleteImageCtx); return nullptr; } - sk_sp releaseHelper( - new GrReleaseProcHelper(deleteImageTexture, new BufferCleanupHelper(image, display))); - tex->setRelease(std::move(releaseHelper)); + sk_sp releaseProcHelper( + new GrReleaseProcHelper(deleteImageProc, deleteImageCtx)); + tex->setRelease(std::move(releaseProcHelper)); // We fail this assert, if the context has changed. This will be fully handled after // skbug.com/6812 is ready. diff --git a/src/gpu/GrAHardwareBufferImageGenerator.h b/src/gpu/GrAHardwareBufferImageGenerator.h index 13f2e1409f..a89e09d4da 100644 --- a/src/gpu/GrAHardwareBufferImageGenerator.h +++ b/src/gpu/GrAHardwareBufferImageGenerator.h @@ -31,6 +31,11 @@ public: ~GrAHardwareBufferImageGenerator() override; + typedef void* DeleteImageCtx; + typedef void (*DeleteImageProc)(DeleteImageCtx); + + static void DeleteEGLImage(void* ctx); + protected: bool onIsValid(GrContext*) const override; @@ -44,8 +49,6 @@ private: sk_sp makeProxy(GrContext* context); void clear(); - static void deleteImageTexture(void* ctx); - AHardwareBuffer* fGraphicBuffer; GrTexture* fOriginalTexture = nullptr; uint32_t fOwningContextID;