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 #include "gpu/GLES2/gl2extchromium.h" 8 #include "third_party/skia/include/core/SkImageInfo.h" 9 10 namespace content { 11 12 GLHelperReadbackSupport::GLHelperReadbackSupport(gpu::gles2::GLES2Interface* gl) 13 : gl_(gl) { 14 InitializeReadbackSupport(); 15 } 16 17 GLHelperReadbackSupport::~GLHelperReadbackSupport() {} 18 19 void GLHelperReadbackSupport::InitializeReadbackSupport() { 20 // We are concerned about 16, 32-bit formats only. The below are the most 21 // used 16, 32-bit formats. In future if any new format support is needed 22 // that should be added here. Initialize the array with 23 // GLHelperReadbackSupport::NOT_SUPPORTED as we dont know the supported 24 // formats yet. 25 for (int i = 0; i <= kLastEnum_SkColorType; ++i) { 26 format_support_table_[i] = GLHelperReadbackSupport::NOT_SUPPORTED; 27 } 28 // TODO(sikugu): kAlpha_8_SkColorType support check is failing on mesa. 29 // See crbug.com/415667. 30 CheckForReadbackSupport(kRGB_565_SkColorType); 31 CheckForReadbackSupport(kARGB_4444_SkColorType); 32 CheckForReadbackSupport(kRGBA_8888_SkColorType); 33 CheckForReadbackSupport(kBGRA_8888_SkColorType); 34 // Further any formats, support should be checked here. 35 } 36 37 void GLHelperReadbackSupport::CheckForReadbackSupport( 38 SkColorType texture_format) { 39 bool supports_format = false; 40 switch (texture_format) { 41 case kRGB_565_SkColorType: 42 supports_format = SupportsFormat(GL_RGB, GL_UNSIGNED_SHORT_5_6_5); 43 break; 44 case kRGBA_8888_SkColorType: 45 // This is the baseline, assume always true. 46 supports_format = true; 47 break; 48 case kBGRA_8888_SkColorType: 49 supports_format = SupportsFormat(GL_BGRA_EXT, GL_UNSIGNED_BYTE); 50 break; 51 case kARGB_4444_SkColorType: 52 supports_format = false; 53 break; 54 default: 55 NOTREACHED(); 56 supports_format = false; 57 break; 58 } 59 DCHECK((int)texture_format <= (int)kLastEnum_SkColorType); 60 format_support_table_[texture_format] = 61 supports_format ? GLHelperReadbackSupport::SUPPORTED 62 : GLHelperReadbackSupport::NOT_SUPPORTED; 63 } 64 65 void GLHelperReadbackSupport::GetAdditionalFormat(GLenum format, 66 GLenum type, 67 GLenum* format_out, 68 GLenum* type_out) { 69 for (unsigned int i = 0; i < format_cache_.size(); i++) { 70 if (format_cache_[i].format == format && format_cache_[i].type == type) { 71 *format_out = format_cache_[i].read_format; 72 *type_out = format_cache_[i].read_type; 73 return; 74 } 75 } 76 77 const int kTestSize = 64; 78 content::ScopedTexture dst_texture(gl_); 79 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture); 80 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 81 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 82 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 83 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 84 gl_->TexImage2D( 85 GL_TEXTURE_2D, 0, format, kTestSize, kTestSize, 0, format, type, NULL); 86 ScopedFramebuffer dst_framebuffer(gl_); 87 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, 88 dst_framebuffer); 89 gl_->FramebufferTexture2D( 90 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_texture, 0); 91 GLint format_tmp = 0, type_tmp = 0; 92 gl_->GetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format_tmp); 93 gl_->GetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &type_tmp); 94 *format_out = format_tmp; 95 *type_out = type_tmp; 96 97 struct FormatCacheEntry entry = { format, type, *format_out, *type_out }; 98 format_cache_.push_back(entry); 99 } 100 101 bool GLHelperReadbackSupport::SupportsFormat(GLenum format, GLenum type) { 102 // GLES2.0 Specification says this pairing is always supported 103 // with additional format from GL_IMPLEMENTATION_COLOR_READ_FORMAT/TYPE 104 if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) 105 return true; 106 107 if (format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) { 108 const GLubyte* tmp = gl_->GetString(GL_EXTENSIONS); 109 if (tmp) { 110 std::string extensions = 111 " " + std::string(reinterpret_cast<const char*>(tmp)) + " "; 112 if (extensions.find(" GL_EXT_read_format_bgra ") != std::string::npos) { 113 return true; 114 } 115 } 116 } 117 118 bool supports_format = false; 119 GLenum ext_format = 0, ext_type = 0; 120 GetAdditionalFormat(format, type, &ext_format, &ext_type); 121 if ((ext_format == format) && (ext_type == type)) { 122 supports_format = true; 123 } 124 return supports_format; 125 } 126 127 GLHelperReadbackSupport::FormatSupport 128 GLHelperReadbackSupport::GetReadbackConfig(SkColorType color_type, 129 bool can_swizzle, 130 GLenum* format, 131 GLenum* type, 132 size_t* bytes_per_pixel) { 133 DCHECK(format && type && bytes_per_pixel); 134 *bytes_per_pixel = 4; 135 *type = GL_UNSIGNED_BYTE; 136 GLenum new_format = 0, new_type = 0; 137 switch (color_type) { 138 case kRGB_565_SkColorType: 139 if (format_support_table_[color_type] == 140 GLHelperReadbackSupport::SUPPORTED) { 141 *format = GL_RGB; 142 *type = GL_UNSIGNED_SHORT_5_6_5; 143 *bytes_per_pixel = 2; 144 return GLHelperReadbackSupport::SUPPORTED; 145 } 146 break; 147 case kRGBA_8888_SkColorType: 148 *format = GL_RGBA; 149 if (can_swizzle) { 150 // If GL_BGRA_EXT is advertised as the readback format through 151 // GL_IMPLEMENTATION_COLOR_READ_FORMAT then assume it is preferred by 152 // the implementation for performance. 153 GetAdditionalFormat(*format, *type, &new_format, &new_type); 154 155 if (new_format == GL_BGRA_EXT && new_type == GL_UNSIGNED_BYTE) { 156 *format = GL_BGRA_EXT; 157 return GLHelperReadbackSupport::SWIZZLE; 158 } 159 } 160 return GLHelperReadbackSupport::SUPPORTED; 161 case kBGRA_8888_SkColorType: 162 *format = GL_BGRA_EXT; 163 if (format_support_table_[color_type] == 164 GLHelperReadbackSupport::SUPPORTED) 165 return GLHelperReadbackSupport::SUPPORTED; 166 167 if (can_swizzle) { 168 *format = GL_RGBA; 169 return GLHelperReadbackSupport::SWIZZLE; 170 } 171 172 break; 173 case kARGB_4444_SkColorType: 174 return GLHelperReadbackSupport::NOT_SUPPORTED; 175 default: 176 NOTREACHED(); 177 break; 178 } 179 180 return GLHelperReadbackSupport::NOT_SUPPORTED; 181 } 182 183 } // namespace content 184