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

Side by Side Diff: ui/ozone/platform/drm/gpu/drm_device.cc

Issue 1182063002: Add support for more advanced color correction (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@qcms-fixed-point-gamma
Patch Set: Refactor for glevin@ and load VCGT always Created 5 years, 1 month 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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 "ui/ozone/platform/drm/gpu/drm_device.h" 5 #include "ui/ozone/platform/drm/gpu/drm_device.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <sys/mman.h> 8 #include <sys/mman.h>
9 #include <unistd.h> 9 #include <unistd.h>
10 #include <xf86drm.h> 10 #include <xf86drm.h>
11 #include <xf86drmMode.h> 11 #include <xf86drmMode.h>
12 12
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/message_loop/message_loop.h" 14 #include "base/message_loop/message_loop.h"
15 #include "base/posix/safe_strerror.h"
15 #include "base/stl_util.h" 16 #include "base/stl_util.h"
16 #include "base/task_runner.h" 17 #include "base/task_runner.h"
17 #include "base/thread_task_runner_handle.h" 18 #include "base/thread_task_runner_handle.h"
18 #include "base/trace_event/trace_event.h" 19 #include "base/trace_event/trace_event.h"
19 #include "third_party/skia/include/core/SkImageInfo.h" 20 #include "third_party/skia/include/core/SkImageInfo.h"
20 #include "ui/display/types/gamma_ramp_rgb_entry.h" 21 #include "ui/display/types/gamma_ramp_rgb_entry.h"
21 #include "ui/ozone/platform/drm/common/drm_util.h" 22 #include "ui/ozone/platform/drm/common/drm_util.h"
22 #include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h" 23 #include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h"
23 24
24 #if defined(USE_DRM_ATOMIC) 25 #if defined(USE_DRM_ATOMIC)
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 } 106 }
106 107
107 bool CanQueryForResources(int fd) { 108 bool CanQueryForResources(int fd) {
108 drm_mode_card_res resources; 109 drm_mode_card_res resources;
109 memset(&resources, 0, sizeof(resources)); 110 memset(&resources, 0, sizeof(resources));
110 // If there is no error getting DRM resources then assume this is a 111 // If there is no error getting DRM resources then assume this is a
111 // modesetting device. 112 // modesetting device.
112 return !drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &resources); 113 return !drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &resources);
113 } 114 }
114 115
116 #ifndef drm_r32g32b32
117 struct drm_r32g32b32 {
118 /*
119 * Data is in U8.24 fixed point format.
120 * All platforms support values within [0, 1.0] range,
121 * for Red, Green and Blue colors.
122 */
123 __u32 r32;
124 __u32 g32;
125 __u32 b32;
126 __u32 reserved;
127 };
128 #endif // drm_r32g32b32
129
130 #ifndef drm_palette
131 struct drm_palette {
132 /*
133 * Starting of palette LUT in R32G32B32 format.
134 * Each of RGB value is in U8.24 fixed point format.
135 */
136 struct drm_r32g32b32 lut[0];
137 };
138 #endif // drm_palette
139
140 #ifndef drm_ctm
141 struct drm_ctm {
142 /*
143 * Each value is in S31.32 format.
144 * This is 3x3 matrix in row major format.
145 * Integer part will be clipped to nearest
146 * max/min boundary as supported by the HW platform.
147 */
148 __s64 ctm_coeff[9];
149 };
150 #endif // drm_ctm
151
152 std::vector<uint8_t> CreateLutBlob(
153 const std::vector<GammaRampRGBEntry>& source) {
154 TRACE_EVENT0("drm", "CreateLutBlob");
155 std::vector<uint8_t> data;
156
157 data.resize(source.size() * sizeof(struct drm_r32g32b32));
158
159 struct drm_palette* palette = reinterpret_cast<struct drm_palette*>(&data[0]);
160
161 for (size_t i = 0; i < source.size(); ++i) {
162 palette->lut[i].r32 = source[i].r;
163 palette->lut[i].g32 = source[i].g;
164 palette->lut[i].b32 = source[i].b;
165 }
166 return data;
167 }
168
169 std::vector<uint8_t> CreateCTMBlob(const float correction_matrix[9]) {
170 std::vector<uint8_t> data;
171 data.resize(sizeof(struct drm_ctm));
172 struct drm_ctm* ctm = reinterpret_cast<struct drm_ctm*>(&data[0]);
173
174 for (int i = 0; i < 9; ++i) {
175 ctm->ctm_coeff[i] = static_cast<uint64_t>(correction_matrix[i] *
176 (static_cast<uint64_t>(1) << 32));
177 }
178
179 return data;
180 }
181
182 bool SetBlobProperty(int fd,
183 uint32_t object_id,
184 uint32_t object_type,
185 uint32_t prop_id,
186 std::vector<uint8_t> data) {
187 uint32_t blob_id;
188 int res;
189 res = drmModeCreatePropertyBlob(fd, &data[0], data.size(), &blob_id);
190 if (res != 0) {
191 LOG(ERROR) << "Error creating property blob: " << base::safe_strerror(res);
192 return false;
193 }
194 res = drmModeObjectSetProperty(fd, object_id, object_type, prop_id, blob_id);
195 if (res != 0) {
196 LOG(ERROR) << "Error updating property: " << base::safe_strerror(res);
197 drmModeDestroyPropertyBlob(fd, blob_id);
198 return false;
199 }
200 drmModeDestroyPropertyBlob(fd, blob_id);
201 return true;
202 }
203
204 std::vector<GammaRampRGBEntry> ResampleLut(
205 const std::vector<GammaRampRGBEntry>& lut_in,
206 size_t desired_size) {
207 TRACE_EVENT1("drm", "ResampleLut", "desired_size", desired_size);
208 if (lut_in.size() == desired_size)
209 return lut_in;
210
211 std::vector<GammaRampRGBEntry> result;
212 result.resize(desired_size);
213
214 #define RESAMPLE(array, m, i, r) \
spang 2015/11/09 19:40:47 Please put a function in the anonymous namespace i
robert.bradford 2016/02/04 18:52:28 Ended up with it inline which worked better than a
215 array[i].m + (array[i + 1].m - array[i].m) * r / desired_size
216
217 for (size_t i = 0; i < desired_size; ++i) {
218 size_t base_index = lut_in.size() * i / desired_size;
219 size_t remaining = lut_in.size() * i % desired_size;
220 if (base_index < lut_in.size() - 1) {
221 result[i].r = RESAMPLE(lut_in, r, base_index, remaining);
222 result[i].g = RESAMPLE(lut_in, g, base_index, remaining);
223 result[i].b = RESAMPLE(lut_in, b, base_index, remaining);
224 } else {
225 result[i] = lut_in[lut_in.size() - 1];
226 }
227 }
228
229 #undef RESAMPLE
230 return result;
231 }
232
115 } // namespace 233 } // namespace
116 234
117 class DrmDevice::PageFlipManager { 235 class DrmDevice::PageFlipManager {
118 public: 236 public:
119 PageFlipManager() : next_id_(0) {} 237 PageFlipManager() : next_id_(0) {}
120 ~PageFlipManager() {} 238 ~PageFlipManager() {}
121 239
122 void OnPageFlip(uint32_t frame, 240 void OnPageFlip(uint32_t frame,
123 uint32_t seconds, 241 uint32_t seconds,
124 uint32_t useconds, 242 uint32_t useconds,
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 g.push_back(lut[i].g); 652 g.push_back(lut[i].g);
535 b.push_back(lut[i].b); 653 b.push_back(lut[i].b);
536 } 654 }
537 655
538 DCHECK(file_.IsValid()); 656 DCHECK(file_.IsValid());
539 TRACE_EVENT0("drm", "DrmDevice::SetGamma"); 657 TRACE_EVENT0("drm", "DrmDevice::SetGamma");
540 return (drmModeCrtcSetGamma(file_.GetPlatformFile(), crtc_id, r.size(), &r[0], 658 return (drmModeCrtcSetGamma(file_.GetPlatformFile(), crtc_id, r.size(), &r[0],
541 &g[0], &b[0]) == 0); 659 &g[0], &b[0]) == 0);
542 } 660 }
543 661
662 bool DrmDevice::SetColorCorrection(
663 uint32_t crtc_id,
664 const std::vector<GammaRampRGBEntry>& degamma_lut,
665 const std::vector<GammaRampRGBEntry>& gamma_lut,
666 const float correction_matrix[9]) {
667 ScopedDrmObjectPropertyPtr crtc_props(drmModeObjectGetProperties(
668 file_.GetPlatformFile(), crtc_id, DRM_MODE_OBJECT_CRTC));
669 uint64_t degamma_lut_size = 0;
670 uint64_t gamma_lut_size = 0;
671
672 for (uint32_t i = 0; i < crtc_props->count_props; ++i) {
673 ScopedDrmPropertyPtr property(
674 drmModeGetProperty(file_.GetPlatformFile(), crtc_props->props[i]));
675 if (property && !strcmp(property->name, "COEFFICIENTS_BEFORE_CTM")) {
676 degamma_lut_size = crtc_props->prop_values[i];
677 }
678 if (property && !strcmp(property->name, "COEFFICIENTS_AFTER_CTM")) {
679 gamma_lut_size = crtc_props->prop_values[i];
680 }
681
682 if (degamma_lut_size && gamma_lut_size)
683 break;
684 }
685
686 if (degamma_lut_size == 0 || gamma_lut_size == 0) {
687 LOG(WARNING) << "No available (de)gamma tables.";
688 return false;
689 }
690
691 std::vector<uint8_t> degamma_blob_data =
692 CreateLutBlob(ResampleLut(degamma_lut, degamma_lut_size));
693 std::vector<uint8_t> gamma_blob_data =
694 CreateLutBlob(ResampleLut(gamma_lut, gamma_lut_size));
695 std::vector<uint8_t> ctm_blob_data = CreateCTMBlob(correction_matrix);
696
697 for (uint32_t i = 0; i < crtc_props->count_props; ++i) {
698 ScopedDrmPropertyPtr property(
699 drmModeGetProperty(file_.GetPlatformFile(), crtc_props->props[i]));
700 if (property && !strcmp(property->name, "PALETTE_BEFORE_CTM")) {
701 if (!SetBlobProperty(file_.GetPlatformFile(), crtc_id,
702 DRM_MODE_OBJECT_CRTC, crtc_props->props[i],
703 degamma_blob_data)) {
704 LOG(WARNING) << "Error setting degamma property.";
705 return false;
706 }
707 }
708 if (property && !strcmp(property->name, "PALETTE_AFTER_CTM")) {
709 if (!SetBlobProperty(file_.GetPlatformFile(), crtc_id,
710 DRM_MODE_OBJECT_CRTC, crtc_props->props[i],
711 gamma_blob_data)) {
712 LOG(WARNING) << "Error setting gamma property.";
713 return false;
714 }
715 }
716 if (property && !strcmp(property->name, "CTM")) {
717 if (!SetBlobProperty(file_.GetPlatformFile(), crtc_id,
718 DRM_MODE_OBJECT_CRTC, crtc_props->props[i],
719 ctm_blob_data)) {
720 LOG(WARNING) << "Error setting correction matrix property.";
721 return false;
722 }
723 }
724 }
725
726 return true;
727 }
728
544 } // namespace ui 729 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698