Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: cc/output/color_lut_cache.cc

Issue 2648043002: Create FP16 LUTs when needed (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/output/color_lut_cache.h ('k') | cc/output/gl_renderer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
11 #include "gpu/command_buffer/client/gles2_interface.h" 11 #include "gpu/command_buffer/client/gles2_interface.h"
12 #include "third_party/khronos/GLES2/gl2ext.h"
12 #include "ui/gfx/color_transform.h" 13 #include "ui/gfx/color_transform.h"
13 14
14 // After a LUT has not been used for this many frames, we release it. 15 // After a LUT has not been used for this many frames, we release it.
15 const uint32_t kMaxFramesUnused = 10; 16 const uint32_t kMaxFramesUnused = 10;
16 17
17 ColorLUTCache::ColorLUTCache(gpu::gles2::GLES2Interface* gl) 18 ColorLUTCache::ColorLUTCache(gpu::gles2::GLES2Interface* gl,
18 : lut_cache_(0), gl_(gl) {} 19 bool texture_half_float_linear)
20 : lut_cache_(0),
21 gl_(gl),
22 texture_half_float_linear_(texture_half_float_linear) {}
19 23
20 ColorLUTCache::~ColorLUTCache() { 24 ColorLUTCache::~ColorLUTCache() {
21 GLuint textures[10]; 25 GLuint textures[10];
22 size_t n = 0; 26 size_t n = 0;
23 for (const auto& cache_entry : lut_cache_) { 27 for (const auto& cache_entry : lut_cache_) {
24 textures[n++] = cache_entry.second.texture; 28 textures[n++] = cache_entry.second.lut.texture;
25 if (n == arraysize(textures)) { 29 if (n == arraysize(textures)) {
26 gl_->DeleteTextures(n, textures); 30 gl_->DeleteTextures(n, textures);
27 n = 0; 31 n = 0;
28 } 32 }
29 } 33 }
30 if (n) 34 if (n)
31 gl_->DeleteTextures(n, textures); 35 gl_->DeleteTextures(n, textures);
32 } 36 }
33 37
34 namespace { 38 namespace {
35 39
36 unsigned char FloatToLUT(float f) { 40 unsigned short baseTable[512] = {
ccameron 2017/01/21 19:49:20 See the source of this block, https://cs.chromium.
hubbe 2017/01/22 05:12:39 That's not actually where I copied it from. Anywho
41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
48 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
50 0, 0, 0, 0, 1, 2, 4, 8, 16, 32, 64,
51 128, 256, 512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192,
52 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 17408, 18432, 19456,
53 20480, 21504, 22528, 23552, 24576, 25600, 26624, 27648, 28672, 29696, 30720,
54 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
55 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
56 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
57 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
58 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
59 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
60 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
61 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
62 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
63 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
64 31744, 31744, 31744, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
65 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
66 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
67 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
68 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
69 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
70 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
71 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
72 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
73 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32769, 32770, 32772, 32776,
74 32784, 32800, 32832, 32896, 33024, 33280, 33792, 34816, 35840, 36864, 37888,
75 38912, 39936, 40960, 41984, 43008, 44032, 45056, 46080, 47104, 48128, 49152,
76 50176, 51200, 52224, 53248, 54272, 55296, 56320, 57344, 58368, 59392, 60416,
77 61440, 62464, 63488, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
78 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
79 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
80 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
81 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
82 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
83 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
84 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
85 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
86 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
87 64512, 64512, 64512, 64512, 64512, 64512};
88
89 unsigned char shiftTable[512] = {
90 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
91 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
92 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
93 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
94 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
95 24, 24, 24, 24, 24, 24, 24, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13,
96 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
97 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 24, 24, 24, 24, 24, 24, 24, 24, 24,
98 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
99 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
100 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
101 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
102 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
103 24, 24, 24, 24, 24, 24, 24, 24, 13, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
104 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
105 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
106 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
107 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
108 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 22,
109 21, 20, 19, 18, 17, 16, 15, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
110 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
111 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
112 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
113 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
114 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
115 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
116 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 13};
117
118 template <typename T>
119 T FloatToLUT(float f) {}
120
121 template <>
122 unsigned short FloatToLUT<unsigned short>(float f) {
123 unsigned temp = *(reinterpret_cast<unsigned*>(&f));
124 unsigned signexp = (temp >> 23) & 0x1ff;
125 return baseTable[signexp] + ((temp & 0x007fffff) >> shiftTable[signexp]);
126 }
127
128 template <>
129 unsigned char FloatToLUT<unsigned char>(float f) {
37 return std::min<int>(255, std::max<int>(0, floorf(f * 255.0f + 0.5f))); 130 return std::min<int>(255, std::max<int>(0, floorf(f * 255.0f + 0.5f)));
38 } 131 }
39 }; 132 };
40 133
134 template <typename T>
41 unsigned int ColorLUTCache::MakeLUT(const gfx::ColorSpace& from, 135 unsigned int ColorLUTCache::MakeLUT(const gfx::ColorSpace& from,
42 gfx::ColorSpace to, 136 gfx::ColorSpace to,
43 int lut_samples) { 137 int lut_samples) {
44 if (to == gfx::ColorSpace()) { 138 if (to == gfx::ColorSpace()) {
45 to = gfx::ColorSpace::CreateSRGB(); 139 to = gfx::ColorSpace::CreateSRGB();
46 } 140 }
47 std::unique_ptr<gfx::ColorTransform> transform( 141 std::unique_ptr<gfx::ColorTransform> transform(
48 gfx::ColorTransform::NewColorTransform( 142 gfx::ColorTransform::NewColorTransform(
49 from, to, gfx::ColorTransform::Intent::INTENT_PERCEPTUAL)); 143 from, to, gfx::ColorTransform::Intent::INTENT_PERCEPTUAL));
50 144
51 int lut_entries = lut_samples * lut_samples * lut_samples; 145 int lut_entries = lut_samples * lut_samples * lut_samples;
52 float inverse = 1.0f / (lut_samples - 1); 146 float inverse = 1.0f / (lut_samples - 1);
53 std::vector<unsigned char> lut(lut_entries * 4); 147 std::vector<T> lut(lut_entries * 4);
54 std::vector<gfx::ColorTransform::TriStim> samples(lut_samples); 148 std::vector<gfx::ColorTransform::TriStim> samples(lut_samples);
55 unsigned char* lutp = lut.data(); 149 T* lutp = lut.data();
56 for (int v = 0; v < lut_samples; v++) { 150 for (int v = 0; v < lut_samples; v++) {
57 for (int u = 0; u < lut_samples; u++) { 151 for (int u = 0; u < lut_samples; u++) {
58 for (int y = 0; y < lut_samples; y++) { 152 for (int y = 0; y < lut_samples; y++) {
59 samples[y].set_x(y * inverse); 153 samples[y].set_x(y * inverse);
60 samples[y].set_y(u * inverse); 154 samples[y].set_y(u * inverse);
61 samples[y].set_z(v * inverse); 155 samples[y].set_z(v * inverse);
62 } 156 }
63 transform->transform(samples.data(), samples.size()); 157 transform->transform(samples.data(), samples.size());
64 for (int y = 0; y < lut_samples; y++) { 158 for (int y = 0; y < lut_samples; y++) {
65 *(lutp++) = FloatToLUT(samples[y].x()); 159 *(lutp++) = FloatToLUT<T>(samples[y].x());
66 *(lutp++) = FloatToLUT(samples[y].y()); 160 *(lutp++) = FloatToLUT<T>(samples[y].y());
67 *(lutp++) = FloatToLUT(samples[y].z()); 161 *(lutp++) = FloatToLUT<T>(samples[y].z());
68 *(lutp++) = 255; // alpha 162 *(lutp++) = FloatToLUT<T>(1.0); // alpha
69 } 163 }
70 } 164 }
71 } 165 }
72 166
73 unsigned int lut_texture; 167 unsigned int lut_texture;
74 gl_->GenTextures(1, &lut_texture); 168 gl_->GenTextures(1, &lut_texture);
75 gl_->BindTexture(GL_TEXTURE_2D, lut_texture); 169 gl_->BindTexture(GL_TEXTURE_2D, lut_texture);
76 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 170 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
77 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 171 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
78 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 172 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
79 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 173 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
ccameron 2017/01/21 01:10:49 To use 16-bit floating point, the upload data does
hubbe 2017/01/22 05:12:39 Done.
80 gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lut_samples, 174 gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lut_samples,
81 lut_samples * lut_samples, 0, GL_RGBA, GL_UNSIGNED_BYTE, 175 lut_samples * lut_samples, 0, GL_RGBA,
176 sizeof(T) == 1 ? GL_UNSIGNED_BYTE : GL_HALF_FLOAT_OES,
82 lut.data()); 177 lut.data());
83 return lut_texture; 178 return lut_texture;
84 } 179 }
85 180
86 unsigned int ColorLUTCache::GetLUT(const gfx::ColorSpace& from, 181 ColorLUTCache::LUT ColorLUTCache::GetLUT(const gfx::ColorSpace& from,
87 const gfx::ColorSpace& to, 182 const gfx::ColorSpace& to) {
88 int lut_samples) { 183 CacheKey key(from, to);
89 CacheKey key(from, std::make_pair(to, lut_samples));
90 auto iter = lut_cache_.Get(key); 184 auto iter = lut_cache_.Get(key);
91 if (iter != lut_cache_.end()) { 185 if (iter != lut_cache_.end()) {
92 iter->second.last_used_frame = current_frame_; 186 iter->second.last_used_frame = current_frame_;
93 return iter->second.texture; 187 return iter->second.lut;
94 } 188 }
95 189
96 unsigned int lut = MakeLUT(from, to, lut_samples); 190 LUT lut;
191 // If input is HDR, and the output is scRGB, we're going to need
192 // to produce values outside of 0-1, so we'll need to make a half-float
193 // LUT. Also, we'll need to build a larger lut to maintain accuracy.
194 // All LUT sizes should be odd a some transforms hav a knee at 0.5.
195 if (to == gfx::ColorSpace::CreateSCRGBLinear() && from.IsHDR() &&
196 texture_half_float_linear_) {
197 lut.size = 37;
198 lut.texture = MakeLUT<unsigned short>(from, to, lut.size);
199 } else {
200 lut.size = 17;
201 lut.texture = MakeLUT<unsigned char>(from, to, lut.size);
202 }
97 lut_cache_.Put(key, CacheVal(lut, current_frame_)); 203 lut_cache_.Put(key, CacheVal(lut, current_frame_));
98 return lut; 204 return lut;
99 } 205 }
100 206
101 void ColorLUTCache::Swap() { 207 void ColorLUTCache::Swap() {
102 current_frame_++; 208 current_frame_++;
103 while (!lut_cache_.empty() && 209 while (!lut_cache_.empty() &&
104 current_frame_ - lut_cache_.rbegin()->second.last_used_frame > 210 current_frame_ - lut_cache_.rbegin()->second.last_used_frame >
105 kMaxFramesUnused) { 211 kMaxFramesUnused) {
106 gl_->DeleteTextures(1, &lut_cache_.rbegin()->second.texture); 212 gl_->DeleteTextures(1, &lut_cache_.rbegin()->second.lut.texture);
107 lut_cache_.ShrinkToSize(lut_cache_.size() - 1); 213 lut_cache_.ShrinkToSize(lut_cache_.size() - 1);
108 } 214 }
109 } 215 }
OLDNEW
« no previous file with comments | « cc/output/color_lut_cache.h ('k') | cc/output/gl_renderer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698