Support more hardware buffer formats
Add support for AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM and
AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM formats.
Handle unknown formats as RGBA.
Bug: 113555199
Change-Id: I95efde5e60ab4b6e8f10a15ae97cf328e6567f10
Reviewed-on: https://skia-review.googlesource.com/150470
Commit-Queue: Stan Iliev <stani@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/GrAHardwareBufferImageGenerator.cpp b/src/gpu/GrAHardwareBufferImageGenerator.cpp
index 332f8c5..981337b 100644
--- a/src/gpu/GrAHardwareBufferImageGenerator.cpp
+++ b/src/gpu/GrAHardwareBufferImageGenerator.cpp
@@ -73,20 +73,34 @@
case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
colorType = kRGB_565_SkColorType;
break;
+ case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
+ case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
+ colorType = kRGB_888x_SkColorType;
+ break;
+ case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
+ colorType = kRGBA_1010102_SkColorType;
+ break;
default:
- return nullptr;
+ // Given that we only use this texture as a source, colorType will not impact how Skia uses
+ // the texture. The only potential affect this is anticipated to have is that for some
+ // format types if we are not bound as an OES texture we may get invalid results for SKP
+ // capture if we read back the texture.
+ colorType = kRGBA_8888_SkColorType;
+ break;
}
SkImageInfo info = SkImageInfo::Make(bufferDesc.width, bufferDesc.height, colorType,
alphaType, std::move(colorSpace));
bool createProtectedImage = 0 != (bufferDesc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT);
return std::unique_ptr<SkImageGenerator>(new GrAHardwareBufferImageGenerator(info, graphicBuffer,
- alphaType, createProtectedImage));
+ alphaType, createProtectedImage, bufferDesc.format));
}
GrAHardwareBufferImageGenerator::GrAHardwareBufferImageGenerator(const SkImageInfo& info,
- AHardwareBuffer* hardwareBuffer, SkAlphaType alphaType, bool isProtectedContent)
+ AHardwareBuffer* hardwareBuffer, SkAlphaType alphaType, bool isProtectedContent,
+ uint32_t bufferFormat)
: INHERITED(info)
, fHardwareBuffer(hardwareBuffer)
+ , fBufferFormat(bufferFormat)
, fIsProtectedContent(isProtectedContent) {
AHardwareBuffer_acquire(fHardwareBuffer);
}
@@ -183,7 +197,8 @@
int width, int height, GrPixelConfig config,
GrAHardwareBufferImageGenerator::DeleteImageProc* deleteProc,
GrAHardwareBufferImageGenerator::DeleteImageCtx* deleteCtx,
- bool isProtectedContent) {
+ bool isProtectedContent,
+ const GrBackendFormat& backendFormat) {
while (GL_NO_ERROR != glGetError()) {} //clear GL errors
EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(hardwareBuffer);
@@ -224,21 +239,10 @@
context->resetContext(kTextureBinding_GrGLBackendState);
GrGLTextureInfo textureInfo;
- textureInfo.fTarget = GL_TEXTURE_EXTERNAL_OES;
textureInfo.fID = texID;
- switch (config) {
- case kRGBA_8888_GrPixelConfig:
- textureInfo.fFormat = GR_GL_RGBA8;
- break;
- case kRGBA_half_GrPixelConfig:
- textureInfo.fFormat = GR_GL_RGBA16F;
- break;
- case kRGB_565_GrPixelConfig:
- textureInfo.fFormat = GR_GL_RGB565;
- break;
- default:
- SkASSERT(false);
- }
+ SkASSERT(backendFormat.isValid());
+ textureInfo.fTarget = *backendFormat.getGLTarget();
+ textureInfo.fFormat = *backendFormat.getGLFormat();
*deleteProc = GrAHardwareBufferImageGenerator::DeleteEGLImage;
*deleteCtx = new BufferCleanupHelper(image, display);
@@ -251,14 +255,15 @@
int width, int height, GrPixelConfig config,
GrAHardwareBufferImageGenerator::DeleteImageProc* deleteProc,
GrAHardwareBufferImageGenerator::DeleteImageCtx* deleteCtx,
- bool isProtectedContent) {
+ bool isProtectedContent,
+ const GrBackendFormat& backendFormat) {
if (context->abandoned() || kOpenGL_GrBackend != context->contextPriv().getBackend()) {
// Check if GrContext is not abandoned and the backend is GL.
return GrBackendTexture();
}
bool createProtectedImage = isProtectedContent && can_import_protected_content(context);
return make_gl_backend_texture(context, hardwareBuffer, width, height, config, deleteProc,
- deleteCtx, createProtectedImage);
+ deleteCtx, createProtectedImage, backendFormat);
}
static void free_backend_texture(GrBackendTexture* backendTexture) {
@@ -277,6 +282,28 @@
}
}
+GrBackendFormat get_backend_format(GrBackend backend, uint32_t bufferFormat) {
+ if (backend == kOpenGL_GrBackend) {
+ switch (bufferFormat) {
+ //TODO: find out if we can detect, which graphic buffers support GR_GL_TEXTURE_2D
+ case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
+ return GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_EXTERNAL);
+ case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
+ return GrBackendFormat::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_EXTERNAL);
+ case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
+ return GrBackendFormat::MakeGL(GR_GL_RGB565, GR_GL_TEXTURE_EXTERNAL);
+ case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
+ return GrBackendFormat::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_EXTERNAL);
+ case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
+ case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
+ return GrBackendFormat::MakeGL(GR_GL_RGB8, GR_GL_TEXTURE_EXTERNAL);
+ default:
+ return GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_EXTERNAL);
+ }
+ }
+ return GrBackendFormat();
+}
+
void GrAHardwareBufferImageGenerator::makeProxy(GrContext* context) {
if (context->abandoned() || kOpenGL_GrBackend != context->contextPriv().getBackend()) {
// Check if GrContext is not abandoned and the backend is GL.
@@ -296,18 +323,11 @@
fOwningContextID = context->uniqueID();
GrPixelConfig pixelConfig;
- 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;
+ GrBackendFormat backendFormat = get_backend_format(context->contextPriv().getBackend(),
+ fBufferFormat);
+ if (!context->contextPriv().caps()->getConfigFromBackendFormat(
+ backendFormat, this->getInfo().colorType(), &pixelConfig)) {
+ return;
}
int width = this->getInfo().width();
@@ -333,7 +353,7 @@
fCachedProxy = proxyProvider->createLazyProxy(
[context, hardwareBuffer, width, height, pixelConfig, ownedTexturePtr,
- isProtectedContent]
+ isProtectedContent, backendFormat]
(GrResourceProvider* resourceProvider) {
if (!resourceProvider) {
AHardwareBuffer_release(hardwareBuffer);
@@ -349,7 +369,8 @@
width, height, pixelConfig,
&deleteImageProc,
&deleteImageCtx,
- isProtectedContent);
+ isProtectedContent,
+ backendFormat);
if (!backendTex.isValid()) {
return sk_sp<GrTexture>();
}
diff --git a/src/gpu/GrAHardwareBufferImageGenerator.h b/src/gpu/GrAHardwareBufferImageGenerator.h
index 3c6f678..1eefe11 100644
--- a/src/gpu/GrAHardwareBufferImageGenerator.h
+++ b/src/gpu/GrAHardwareBufferImageGenerator.h
@@ -48,7 +48,7 @@
private:
GrAHardwareBufferImageGenerator(const SkImageInfo&, AHardwareBuffer*, SkAlphaType,
- bool isProtectedContent);
+ bool isProtectedContent, uint32_t bufferFormat);
void makeProxy(GrContext* context);
void releaseTextureRef();
@@ -62,6 +62,7 @@
// avoid releasing a ref from another thread, or get into races during context shutdown.
GrTexture* fOwnedTexture = nullptr;
uint32_t fOwningContextID = SK_InvalidGenID;
+ uint32_t fBufferFormat;
sk_sp<GrTextureProxy> fCachedProxy;
const bool fIsProtectedContent;