Home | History | Annotate | Download | only in client
      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