| OLD | NEW | 
|    1 // Copyright 2016 The Chromium Authors. All rights reserved. |    1 // Copyright 2016 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "cc/output/color_lut_cache.h" |    5 #include "cc/output/color_lut_cache.h" | 
|    6  |    6  | 
|    7 #include <stdint.h> |    7 #include <stdint.h> | 
|    8 #include <cmath> |    8 #include <cmath> | 
|    9 #include <vector> |    9 #include <vector> | 
|   10  |   10  | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   44  |   44  | 
|   45 void FloatToLUT(float* f, unsigned char* out, size_t num) { |   45 void FloatToLUT(float* f, unsigned char* out, size_t num) { | 
|   46   for (size_t i = 0; i < num; i++) { |   46   for (size_t i = 0; i < num; i++) { | 
|   47     out[i] = std::min<int>(255, std::max<int>(0, floorf(f[i] * 255.0f + 0.5f))); |   47     out[i] = std::min<int>(255, std::max<int>(0, floorf(f[i] * 255.0f + 0.5f))); | 
|   48   } |   48   } | 
|   49 } |   49 } | 
|   50  |   50  | 
|   51 }  // namespace |   51 }  // namespace | 
|   52  |   52  | 
|   53 template <typename T> |   53 template <typename T> | 
|   54 unsigned int ColorLUTCache::MakeLUT(const gfx::ColorSpace& from, |   54 unsigned int ColorLUTCache::MakeLUT(const gfx::ColorTransform* transform, | 
|   55                                     gfx::ColorSpace to, |  | 
|   56                                     int lut_samples) { |   55                                     int lut_samples) { | 
|   57   if (to == gfx::ColorSpace()) { |  | 
|   58     to = gfx::ColorSpace::CreateSRGB(); |  | 
|   59   } |  | 
|   60   std::unique_ptr<gfx::ColorTransform> transform( |  | 
|   61       gfx::ColorTransform::NewColorTransform( |  | 
|   62           from, to, gfx::ColorTransform::Intent::INTENT_PERCEPTUAL)); |  | 
|   63  |  | 
|   64   int lut_entries = lut_samples * lut_samples * lut_samples; |   56   int lut_entries = lut_samples * lut_samples * lut_samples; | 
|   65   float inverse = 1.0f / (lut_samples - 1); |   57   float inverse = 1.0f / (lut_samples - 1); | 
|   66   std::vector<T> lut(lut_entries * 4); |   58   std::vector<T> lut(lut_entries * 4); | 
|   67   std::vector<gfx::ColorTransform::TriStim> samples(lut_samples); |   59   std::vector<gfx::ColorTransform::TriStim> samples(lut_samples); | 
|   68   T* lutp = lut.data(); |   60   T* lutp = lut.data(); | 
|   69   float one = 1.0f; |   61   float one = 1.0f; | 
|   70   T alpha; |   62   T alpha; | 
|   71   FloatToLUT(&one, &alpha, 1); |   63   FloatToLUT(&one, &alpha, 1); | 
|   72   for (int v = 0; v < lut_samples; v++) { |   64   for (int v = 0; v < lut_samples; v++) { | 
|   73     for (int u = 0; u < lut_samples; u++) { |   65     for (int u = 0; u < lut_samples; u++) { | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|   96   gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |   88   gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 
|   97   gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |   89   gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 
|   98   gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |   90   gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 
|   99   gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lut_samples, |   91   gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lut_samples, | 
|  100                   lut_samples * lut_samples, 0, GL_RGBA, |   92                   lut_samples * lut_samples, 0, GL_RGBA, | 
|  101                   sizeof(T) == 1 ? GL_UNSIGNED_BYTE : GL_HALF_FLOAT_OES, |   93                   sizeof(T) == 1 ? GL_UNSIGNED_BYTE : GL_HALF_FLOAT_OES, | 
|  102                   lut.data()); |   94                   lut.data()); | 
|  103   return lut_texture; |   95   return lut_texture; | 
|  104 } |   96 } | 
|  105  |   97  | 
|  106 ColorLUTCache::LUT ColorLUTCache::GetLUT(const gfx::ColorSpace& from, |   98 ColorLUTCache::LUT ColorLUTCache::GetLUT(const gfx::ColorTransform* transform) { | 
|  107                                          const gfx::ColorSpace& to) { |   99   auto iter = lut_cache_.Get(transform); | 
|  108   CacheKey key(from, to); |  | 
|  109   auto iter = lut_cache_.Get(key); |  | 
|  110   if (iter != lut_cache_.end()) { |  100   if (iter != lut_cache_.end()) { | 
|  111     iter->second.last_used_frame = current_frame_; |  101     iter->second.last_used_frame = current_frame_; | 
|  112     return iter->second.lut; |  102     return iter->second.lut; | 
|  113   } |  103   } | 
|  114  |  104  | 
|  115   LUT lut; |  105   LUT lut; | 
|  116   // If input is HDR, and the output is scRGB, we're going to need |  106   // If input is HDR, and the output is scRGB, we're going to need | 
|  117   // to produce values outside of 0-1, so we'll need to make a half-float |  107   // to produce values outside of 0-1, so we'll need to make a half-float | 
|  118   // LUT. Also, we'll need to build a larger lut to maintain accuracy. |  108   // LUT. Also, we'll need to build a larger lut to maintain accuracy. | 
|  119   // All LUT sizes should be odd a some transforms hav a knee at 0.5. |  109   // All LUT sizes should be odd a some transforms hav a knee at 0.5. | 
|  120   if (to == gfx::ColorSpace::CreateSCRGBLinear() && from.IsHDR() && |  110   if (transform->GetDstColorSpace() == gfx::ColorSpace::CreateSCRGBLinear() && | 
|  121       texture_half_float_linear_) { |  111       transform->GetSrcColorSpace().IsHDR() && texture_half_float_linear_) { | 
|  122     lut.size = 37; |  112     lut.size = 37; | 
|  123     lut.texture = MakeLUT<uint16_t>(from, to, lut.size); |  113     lut.texture = MakeLUT<uint16_t>(transform, lut.size); | 
|  124   } else { |  114   } else { | 
|  125     lut.size = 17; |  115     lut.size = 17; | 
|  126     lut.texture = MakeLUT<unsigned char>(from, to, lut.size); |  116     lut.texture = MakeLUT<unsigned char>(transform, lut.size); | 
|  127   } |  117   } | 
|  128   lut_cache_.Put(key, CacheVal(lut, current_frame_)); |  118   lut_cache_.Put(transform, CacheVal(lut, current_frame_)); | 
|  129   return lut; |  119   return lut; | 
|  130 } |  120 } | 
|  131  |  121  | 
|  132 void ColorLUTCache::Swap() { |  122 void ColorLUTCache::Swap() { | 
|  133   current_frame_++; |  123   current_frame_++; | 
|  134   while (!lut_cache_.empty() && |  124   while (!lut_cache_.empty() && | 
|  135          current_frame_ - lut_cache_.rbegin()->second.last_used_frame > |  125          current_frame_ - lut_cache_.rbegin()->second.last_used_frame > | 
|  136              kMaxFramesUnused) { |  126              kMaxFramesUnused) { | 
|  137     gl_->DeleteTextures(1, &lut_cache_.rbegin()->second.lut.texture); |  127     gl_->DeleteTextures(1, &lut_cache_.rbegin()->second.lut.texture); | 
|  138     lut_cache_.ShrinkToSize(lut_cache_.size() - 1); |  128     lut_cache_.ShrinkToSize(lut_cache_.size() - 1); | 
|  139   } |  129   } | 
|  140 } |  130 } | 
| OLD | NEW |