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 <brianosman@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/GrAHardwareBufferImageGenerator.cpp b/src/gpu/GrAHardwareBufferImageGenerator.cpp
index 2b38a60..e69467c 100644
--- a/src/gpu/GrAHardwareBufferImageGenerator.cpp
+++ b/src/gpu/GrAHardwareBufferImageGenerator.cpp
@@ -29,19 +29,6 @@
#include <GLES/gl.h>
#include <GLES/glext.h>
-class BufferCleanupHelper {
-public:
- BufferCleanupHelper(EGLImageKHR image, EGLDisplay display)
- : fImage(image)
- , fDisplay(display) { }
- ~BufferCleanupHelper() {
- eglDestroyImageKHR(fDisplay, fImage);
- }
-private:
- EGLImageKHR fImage;
- EGLDisplay fDisplay;
-};
-
std::unique_ptr<SkImageGenerator> GrAHardwareBufferImageGenerator::Make(
AHardwareBuffer* graphicBuffer, SkAlphaType alphaType, sk_sp<SkColorSpace> colorSpace) {
AHardwareBuffer_Desc bufferDesc;
@@ -88,11 +75,6 @@
}
}
-void GrAHardwareBufferImageGenerator::deleteImageTexture(void* context) {
- BufferCleanupHelper* cleanupHelper = static_cast<BufferCleanupHelper*>(context);
- delete cleanupHelper;
-}
-
///////////////////////////////////////////////////////////////////////////////////////////////////
sk_sp<GrTextureProxy> GrAHardwareBufferImageGenerator::onGenerateTexture(
@@ -104,7 +86,7 @@
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 @@
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<BufferCleanupHelper*>(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<GrTextureProxy> 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 @@
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<GrTexture> 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<GrReleaseProcHelper> releaseHelper(
- new GrReleaseProcHelper(deleteImageTexture, new BufferCleanupHelper(image, display)));
- tex->setRelease(std::move(releaseHelper));
+ sk_sp<GrReleaseProcHelper> 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.