1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "content/common/gpu/client/gl_helper_readback_support.h" 6 #include "base/logging.h" 7 8 namespace content { 9 10 GLHelperReadbackSupport::GLHelperReadbackSupport(gpu::gles2::GLES2Interface* gl) 11 : gl_(gl) { 12 InitializeReadbackSupport(); 13 } 14 15 GLHelperReadbackSupport::~GLHelperReadbackSupport() {} 16 17 void GLHelperReadbackSupport::InitializeReadbackSupport() { 18 // We are concerned about 16, 32-bit formats only. 19 // The below are the most used 16, 32-bit formats. 20 // In future if any new format support is needed that should be added here. 21 // Initialize the array with FORMAT_NOT_SUPPORTED as we dont know the 22 // supported formats yet. 23 for (int i = 0; i < SkBitmap::kConfigCount; ++i) { 24 format_support_table_[i] = FORMAT_NOT_SUPPORTED; 25 } 26 CheckForReadbackSupport(SkBitmap::kRGB_565_Config); 27 CheckForReadbackSupport(SkBitmap::kARGB_4444_Config); 28 CheckForReadbackSupport(SkBitmap::kARGB_8888_Config); 29 // Further any formats, support should be checked here. 30 } 31 32 void GLHelperReadbackSupport::CheckForReadbackSupport( 33 SkBitmap::Config texture_format) { 34 bool supports_format = false; 35 switch (texture_format) { 36 case SkBitmap::kRGB_565_Config: 37 supports_format = SupportsFormat(GL_RGB, GL_UNSIGNED_SHORT_5_6_5); 38 break; 39 case SkBitmap::kARGB_8888_Config: 40 // This is the baseline, assume always true. 41 supports_format = true; 42 break; 43 case SkBitmap::kARGB_4444_Config: 44 supports_format = false; 45 break; 46 default: 47 NOTREACHED(); 48 supports_format = false; 49 break; 50 } 51 DCHECK((int)texture_format < (int)SkBitmap::kConfigCount); 52 format_support_table_[texture_format] = 53 supports_format ? FORMAT_SUPPORTED : FORMAT_NOT_SUPPORTED; 54 } 55 56 void GLHelperReadbackSupport::GetAdditionalFormat(GLint format, GLint type, 57 GLint *format_out, 58 GLint *type_out) { 59 for (unsigned int i = 0; i < format_cache_.size(); i++) { 60 if (format_cache_[i].format == format && format_cache_[i].type == type) { 61 *format_out = format_cache_[i].read_format; 62 *type_out = format_cache_[i].read_type; 63 return; 64 } 65 } 66 67 const int kTestSize = 64; 68 content::ScopedTexture dst_texture(gl_); 69 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture); 70 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 71 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 72 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 73 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 74 gl_->TexImage2D( 75 GL_TEXTURE_2D, 0, format, kTestSize, kTestSize, 0, format, type, NULL); 76 ScopedFramebuffer dst_framebuffer(gl_); 77 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, 78 dst_framebuffer); 79 gl_->FramebufferTexture2D( 80 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_texture, 0); 81 gl_->GetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, format_out); 82 gl_->GetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, type_out); 83 84 struct FormatCacheEntry entry = { format, type, *format_out, *type_out }; 85 format_cache_.push_back(entry); 86 } 87 88 bool GLHelperReadbackSupport::SupportsFormat(GLint format, GLint type) { 89 // GLES2.0 Specification says this pairing is always supported 90 // with additional format from GL_IMPLEMENTATION_COLOR_READ_FORMAT/TYPE 91 if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) 92 return true; 93 bool supports_format = false; 94 GLint ext_format = 0, ext_type = 0; 95 GetAdditionalFormat(format, type, &ext_format, &ext_type); 96 if ((ext_format == format) && (ext_type == type)) { 97 supports_format = true; 98 } 99 return supports_format; 100 } 101 102 bool GLHelperReadbackSupport::IsReadbackConfigSupported( 103 SkBitmap::Config texture_format) { 104 switch (format_support_table_[texture_format]) { 105 case FORMAT_SUPPORTED: 106 return true; 107 case FORMAT_NOT_SUPPORTED: 108 return false; 109 default: 110 NOTREACHED(); 111 return false; 112 } 113 } 114 115 } // namespace content 116