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

Unified 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/output/color_lut_cache.cc
diff --git a/cc/output/color_lut_cache.cc b/cc/output/color_lut_cache.cc
index d591f39fbcb898079c644ec714d42df21a365f64..2409fcd316c475f2e098f816af4d1f40e52a0903 100644
--- a/cc/output/color_lut_cache.cc
+++ b/cc/output/color_lut_cache.cc
@@ -9,19 +9,23 @@
#include <vector>
#include "gpu/command_buffer/client/gles2_interface.h"
+#include "third_party/khronos/GLES2/gl2ext.h"
#include "ui/gfx/color_transform.h"
// After a LUT has not been used for this many frames, we release it.
const uint32_t kMaxFramesUnused = 10;
-ColorLUTCache::ColorLUTCache(gpu::gles2::GLES2Interface* gl)
- : lut_cache_(0), gl_(gl) {}
+ColorLUTCache::ColorLUTCache(gpu::gles2::GLES2Interface* gl,
+ bool texture_half_float_linear)
+ : lut_cache_(0),
+ gl_(gl),
+ texture_half_float_linear_(texture_half_float_linear) {}
ColorLUTCache::~ColorLUTCache() {
GLuint textures[10];
size_t n = 0;
for (const auto& cache_entry : lut_cache_) {
- textures[n++] = cache_entry.second.texture;
+ textures[n++] = cache_entry.second.lut.texture;
if (n == arraysize(textures)) {
gl_->DeleteTextures(n, textures);
n = 0;
@@ -33,11 +37,101 @@ ColorLUTCache::~ColorLUTCache() {
namespace {
-unsigned char FloatToLUT(float f) {
+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
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 2, 4, 8, 16, 32, 64,
+ 128, 256, 512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192,
+ 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 17408, 18432, 19456,
+ 20480, 21504, 22528, 23552, 24576, 25600, 26624, 27648, 28672, 29696, 30720,
+ 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
+ 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
+ 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
+ 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
+ 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
+ 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
+ 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
+ 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
+ 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
+ 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
+ 31744, 31744, 31744, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
+ 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
+ 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
+ 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
+ 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
+ 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
+ 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
+ 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
+ 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
+ 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32769, 32770, 32772, 32776,
+ 32784, 32800, 32832, 32896, 33024, 33280, 33792, 34816, 35840, 36864, 37888,
+ 38912, 39936, 40960, 41984, 43008, 44032, 45056, 46080, 47104, 48128, 49152,
+ 50176, 51200, 52224, 53248, 54272, 55296, 56320, 57344, 58368, 59392, 60416,
+ 61440, 62464, 63488, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
+ 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
+ 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
+ 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
+ 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
+ 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
+ 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
+ 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
+ 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
+ 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
+ 64512, 64512, 64512, 64512, 64512, 64512};
+
+unsigned char shiftTable[512] = {
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 13, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 22,
+ 21, 20, 19, 18, 17, 16, 15, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 13};
+
+template <typename T>
+T FloatToLUT(float f) {}
+
+template <>
+unsigned short FloatToLUT<unsigned short>(float f) {
+ unsigned temp = *(reinterpret_cast<unsigned*>(&f));
+ unsigned signexp = (temp >> 23) & 0x1ff;
+ return baseTable[signexp] + ((temp & 0x007fffff) >> shiftTable[signexp]);
+}
+
+template <>
+unsigned char FloatToLUT<unsigned char>(float f) {
return std::min<int>(255, std::max<int>(0, floorf(f * 255.0f + 0.5f)));
}
};
+template <typename T>
unsigned int ColorLUTCache::MakeLUT(const gfx::ColorSpace& from,
gfx::ColorSpace to,
int lut_samples) {
@@ -50,9 +144,9 @@ unsigned int ColorLUTCache::MakeLUT(const gfx::ColorSpace& from,
int lut_entries = lut_samples * lut_samples * lut_samples;
float inverse = 1.0f / (lut_samples - 1);
- std::vector<unsigned char> lut(lut_entries * 4);
+ std::vector<T> lut(lut_entries * 4);
std::vector<gfx::ColorTransform::TriStim> samples(lut_samples);
- unsigned char* lutp = lut.data();
+ T* lutp = lut.data();
for (int v = 0; v < lut_samples; v++) {
for (int u = 0; u < lut_samples; u++) {
for (int y = 0; y < lut_samples; y++) {
@@ -62,10 +156,10 @@ unsigned int ColorLUTCache::MakeLUT(const gfx::ColorSpace& from,
}
transform->transform(samples.data(), samples.size());
for (int y = 0; y < lut_samples; y++) {
- *(lutp++) = FloatToLUT(samples[y].x());
- *(lutp++) = FloatToLUT(samples[y].y());
- *(lutp++) = FloatToLUT(samples[y].z());
- *(lutp++) = 255; // alpha
+ *(lutp++) = FloatToLUT<T>(samples[y].x());
+ *(lutp++) = FloatToLUT<T>(samples[y].y());
+ *(lutp++) = FloatToLUT<T>(samples[y].z());
+ *(lutp++) = FloatToLUT<T>(1.0); // alpha
}
}
}
@@ -78,22 +172,34 @@ unsigned int ColorLUTCache::MakeLUT(const gfx::ColorSpace& from,
gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
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.
gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lut_samples,
- lut_samples * lut_samples, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ lut_samples * lut_samples, 0, GL_RGBA,
+ sizeof(T) == 1 ? GL_UNSIGNED_BYTE : GL_HALF_FLOAT_OES,
lut.data());
return lut_texture;
}
-unsigned int ColorLUTCache::GetLUT(const gfx::ColorSpace& from,
- const gfx::ColorSpace& to,
- int lut_samples) {
- CacheKey key(from, std::make_pair(to, lut_samples));
+ColorLUTCache::LUT ColorLUTCache::GetLUT(const gfx::ColorSpace& from,
+ const gfx::ColorSpace& to) {
+ CacheKey key(from, to);
auto iter = lut_cache_.Get(key);
if (iter != lut_cache_.end()) {
iter->second.last_used_frame = current_frame_;
- return iter->second.texture;
+ return iter->second.lut;
}
- unsigned int lut = MakeLUT(from, to, lut_samples);
+ LUT lut;
+ // If input is HDR, and the output is scRGB, we're going to need
+ // to produce values outside of 0-1, so we'll need to make a half-float
+ // LUT. Also, we'll need to build a larger lut to maintain accuracy.
+ // All LUT sizes should be odd a some transforms hav a knee at 0.5.
+ if (to == gfx::ColorSpace::CreateSCRGBLinear() && from.IsHDR() &&
+ texture_half_float_linear_) {
+ lut.size = 37;
+ lut.texture = MakeLUT<unsigned short>(from, to, lut.size);
+ } else {
+ lut.size = 17;
+ lut.texture = MakeLUT<unsigned char>(from, to, lut.size);
+ }
lut_cache_.Put(key, CacheVal(lut, current_frame_));
return lut;
}
@@ -103,7 +209,7 @@ void ColorLUTCache::Swap() {
while (!lut_cache_.empty() &&
current_frame_ - lut_cache_.rbegin()->second.last_used_frame >
kMaxFramesUnused) {
- gl_->DeleteTextures(1, &lut_cache_.rbegin()->second.texture);
+ gl_->DeleteTextures(1, &lut_cache_.rbegin()->second.lut.texture);
lut_cache_.ShrinkToSize(lut_cache_.size() - 1);
}
}
« 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