| OLD | NEW |
| 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> |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 ret = drmIoctl(fd, DRM_IOCTL_MODE_DESTROYPROPBLOB, &destroy); | 178 ret = drmIoctl(fd, DRM_IOCTL_MODE_DESTROYPROPBLOB, &destroy); |
| 179 return ret < 0 ? -errno : ret; | 179 return ret < 0 ? -errno : ret; |
| 180 } | 180 } |
| 181 | 181 |
| 182 using ScopedDrmColorLutPtr = std::unique_ptr<DrmColorLut, base::FreeDeleter>; | 182 using ScopedDrmColorLutPtr = std::unique_ptr<DrmColorLut, base::FreeDeleter>; |
| 183 using ScopedDrmColorCtmPtr = std::unique_ptr<DrmColorCtm, base::FreeDeleter>; | 183 using ScopedDrmColorCtmPtr = std::unique_ptr<DrmColorCtm, base::FreeDeleter>; |
| 184 | 184 |
| 185 ScopedDrmColorLutPtr CreateLutBlob( | 185 ScopedDrmColorLutPtr CreateLutBlob( |
| 186 const std::vector<GammaRampRGBEntry>& source) { | 186 const std::vector<GammaRampRGBEntry>& source) { |
| 187 TRACE_EVENT0("drm", "CreateLutBlob"); | 187 TRACE_EVENT0("drm", "CreateLutBlob"); |
| 188 if (source.empty()) | |
| 189 return nullptr; | |
| 190 | |
| 191 ScopedDrmColorLutPtr lut( | 188 ScopedDrmColorLutPtr lut( |
| 192 static_cast<DrmColorLut*>(malloc(sizeof(DrmColorLut) * source.size()))); | 189 static_cast<DrmColorLut*>(malloc(sizeof(DrmColorLut) * source.size()))); |
| 193 DrmColorLut* p = lut.get(); | 190 DrmColorLut* p = lut.get(); |
| 194 for (size_t i = 0; i < source.size(); ++i) { | 191 for (size_t i = 0; i < source.size(); ++i) { |
| 195 p[i].red = source[i].r; | 192 p[i].red = source[i].r; |
| 196 p[i].green = source[i].g; | 193 p[i].green = source[i].g; |
| 197 p[i].blue = source[i].b; | 194 p[i].blue = source[i].b; |
| 198 } | 195 } |
| 199 return lut; | 196 return lut; |
| 200 } | 197 } |
| 201 | 198 |
| 202 ScopedDrmColorCtmPtr CreateCTMBlob( | 199 ScopedDrmColorCtmPtr CreateCTMBlob( |
| 203 const std::vector<float>& correction_matrix) { | 200 const std::vector<float>& correction_matrix) { |
| 204 if (correction_matrix.empty()) | |
| 205 return nullptr; | |
| 206 | |
| 207 ScopedDrmColorCtmPtr ctm( | 201 ScopedDrmColorCtmPtr ctm( |
| 208 static_cast<DrmColorCtm*>(malloc(sizeof(DrmColorCtm)))); | 202 static_cast<DrmColorCtm*>(malloc(sizeof(DrmColorCtm)))); |
| 209 for (size_t i = 0; i < arraysize(ctm->ctm_coeff); ++i) { | 203 for (size_t i = 0; i < arraysize(ctm->ctm_coeff); ++i) { |
| 210 if (correction_matrix[i] < 0) { | 204 if (correction_matrix[i] < 0) { |
| 211 ctm->ctm_coeff[i] = static_cast<uint64_t>( | 205 ctm->ctm_coeff[i] = static_cast<uint64_t>( |
| 212 -correction_matrix[i] * (static_cast<uint64_t>(1) << 32)); | 206 -correction_matrix[i] * (static_cast<uint64_t>(1) << 32)); |
| 213 ctm->ctm_coeff[i] |= static_cast<uint64_t>(1) << 63; | 207 ctm->ctm_coeff[i] |= static_cast<uint64_t>(1) << 63; |
| 214 } else { | 208 } else { |
| 215 ctm->ctm_coeff[i] = static_cast<uint64_t>( | 209 ctm->ctm_coeff[i] = static_cast<uint64_t>( |
| 216 correction_matrix[i] * (static_cast<uint64_t>(1) << 32)); | 210 correction_matrix[i] * (static_cast<uint64_t>(1) << 32)); |
| 217 } | 211 } |
| 218 } | 212 } |
| 219 return ctm; | 213 return ctm; |
| 220 } | 214 } |
| 221 | 215 |
| 222 bool SetBlobProperty(int fd, | 216 bool SetBlobProperty(int fd, |
| 223 uint32_t object_id, | 217 uint32_t object_id, |
| 224 uint32_t object_type, | 218 uint32_t object_type, |
| 225 uint32_t prop_id, | 219 uint32_t prop_id, |
| 226 const char* property_name, | 220 const char* property_name, |
| 227 unsigned char* data, | 221 unsigned char* data, |
| 228 size_t length) { | 222 size_t length) { |
| 229 uint32_t blob_id = 0; | 223 uint32_t blob_id; |
| 230 int res; | 224 int res; |
| 231 | 225 res = CreatePropertyBlob(fd, data, length, &blob_id); |
| 232 if (data) { | 226 if (res != 0) { |
| 233 res = CreatePropertyBlob(fd, data, length, &blob_id); | 227 LOG(ERROR) << "Error creating property blob: " << base::safe_strerror(res) |
| 234 if (res != 0) { | 228 << " for property " << property_name; |
| 235 LOG(ERROR) << "Error creating property blob: " << base::safe_strerror(res) | 229 return false; |
| 236 << " for property " << property_name; | |
| 237 return false; | |
| 238 } | |
| 239 } | 230 } |
| 240 | |
| 241 bool success = false; | |
| 242 res = drmModeObjectSetProperty(fd, object_id, object_type, prop_id, blob_id); | 231 res = drmModeObjectSetProperty(fd, object_id, object_type, prop_id, blob_id); |
| 243 if (res != 0) { | 232 if (res != 0) { |
| 244 LOG(ERROR) << "Error updating property: " << base::safe_strerror(res) | 233 LOG(ERROR) << "Error updating property: " << base::safe_strerror(res) |
| 245 << " for property " << property_name; | 234 << " for property " << property_name; |
| 246 } else { | 235 DestroyPropertyBlob(fd, blob_id); |
| 247 success = true; | 236 return false; |
| 248 } | 237 } |
| 249 if (blob_id != 0) | 238 DestroyPropertyBlob(fd, blob_id); |
| 250 DestroyPropertyBlob(fd, blob_id); | 239 return true; |
| 251 return success; | |
| 252 } | 240 } |
| 253 | 241 |
| 254 std::vector<GammaRampRGBEntry> ResampleLut( | 242 std::vector<GammaRampRGBEntry> ResampleLut( |
| 255 const std::vector<GammaRampRGBEntry>& lut_in, | 243 const std::vector<GammaRampRGBEntry>& lut_in, |
| 256 size_t desired_size) { | 244 size_t desired_size) { |
| 257 TRACE_EVENT1("drm", "ResampleLut", "desired_size", desired_size); | 245 TRACE_EVENT1("drm", "ResampleLut", "desired_size", desired_size); |
| 258 if (lut_in.empty()) | |
| 259 return std::vector<GammaRampRGBEntry>(); | |
| 260 | |
| 261 if (lut_in.size() == desired_size) | 246 if (lut_in.size() == desired_size) |
| 262 return lut_in; | 247 return lut_in; |
| 263 | 248 |
| 264 std::vector<GammaRampRGBEntry> result; | 249 std::vector<GammaRampRGBEntry> result; |
| 265 result.resize(desired_size); | 250 result.resize(desired_size); |
| 266 | 251 |
| 267 for (size_t i = 0; i < desired_size; ++i) { | 252 for (size_t i = 0; i < desired_size; ++i) { |
| 268 size_t base_index = lut_in.size() * i / desired_size; | 253 size_t base_index = lut_in.size() * i / desired_size; |
| 269 size_t remaining = lut_in.size() * i % desired_size; | 254 size_t remaining = lut_in.size() * i % desired_size; |
| 270 if (base_index < lut_in.size() - 1) { | 255 if (base_index < lut_in.size() - 1) { |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 682 | 667 |
| 683 bool DrmDevice::DropMaster() { | 668 bool DrmDevice::DropMaster() { |
| 684 TRACE_EVENT1("drm", "DrmDevice::DropMaster", "path", device_path_.value()); | 669 TRACE_EVENT1("drm", "DrmDevice::DropMaster", "path", device_path_.value()); |
| 685 DCHECK(file_.IsValid()); | 670 DCHECK(file_.IsValid()); |
| 686 return (drmDropMaster(file_.GetPlatformFile()) == 0); | 671 return (drmDropMaster(file_.GetPlatformFile()) == 0); |
| 687 } | 672 } |
| 688 | 673 |
| 689 bool DrmDevice::SetGammaRamp(uint32_t crtc_id, | 674 bool DrmDevice::SetGammaRamp(uint32_t crtc_id, |
| 690 const std::vector<GammaRampRGBEntry>& lut) { | 675 const std::vector<GammaRampRGBEntry>& lut) { |
| 691 ScopedDrmCrtcPtr crtc = GetCrtc(crtc_id); | 676 ScopedDrmCrtcPtr crtc = GetCrtc(crtc_id); |
| 692 size_t gamma_size = static_cast<size_t>(crtc->gamma_size); | |
| 693 | 677 |
| 694 // TODO(robert.bradford) resample the incoming ramp to match what the kernel | 678 // TODO(robert.bradford) resample the incoming ramp to match what the kernel |
| 695 // expects. | 679 // expects. |
| 696 if (!lut.empty() && gamma_size != lut.size()) { | 680 if (static_cast<size_t>(crtc->gamma_size) != lut.size()) { |
| 697 LOG(ERROR) << "Gamma table size mismatch: supplied " << lut.size() | 681 LOG(ERROR) << "Gamma table size mismatch: supplied " << lut.size() |
| 698 << " expected " << gamma_size; | 682 << " expected " << crtc->gamma_size; |
| 699 return false; | |
| 700 } | 683 } |
| 701 | 684 |
| 702 std::vector<uint16_t> r, g, b; | 685 std::vector<uint16_t> r, g, b; |
| 703 r.reserve(gamma_size); | 686 r.reserve(lut.size()); |
| 704 g.reserve(gamma_size); | 687 g.reserve(lut.size()); |
| 705 b.reserve(gamma_size); | 688 b.reserve(lut.size()); |
| 706 | 689 |
| 707 if (lut.empty()) { | 690 for (size_t i = 0; i < lut.size(); ++i) { |
| 708 // Create a linear gamma ramp table to deactivate the feature. | 691 r.push_back(lut[i].r); |
| 709 for (size_t i = 0; i < gamma_size; ++i) { | 692 g.push_back(lut[i].g); |
| 710 uint16_t value = (i * ((1 << 16) - 1)) / (gamma_size - 1); | 693 b.push_back(lut[i].b); |
| 711 r.push_back(value); | |
| 712 g.push_back(value); | |
| 713 b.push_back(value); | |
| 714 } | |
| 715 } else { | |
| 716 for (size_t i = 0; i < gamma_size; ++i) { | |
| 717 r.push_back(lut[i].r); | |
| 718 g.push_back(lut[i].g); | |
| 719 b.push_back(lut[i].b); | |
| 720 } | |
| 721 } | 694 } |
| 722 | 695 |
| 723 DCHECK(file_.IsValid()); | 696 DCHECK(file_.IsValid()); |
| 724 TRACE_EVENT0("drm", "DrmDevice::SetGamma"); | 697 TRACE_EVENT0("drm", "DrmDevice::SetGamma"); |
| 725 return (drmModeCrtcSetGamma(file_.GetPlatformFile(), crtc_id, r.size(), &r[0], | 698 return (drmModeCrtcSetGamma(file_.GetPlatformFile(), crtc_id, r.size(), &r[0], |
| 726 &g[0], &b[0]) == 0); | 699 &g[0], &b[0]) == 0); |
| 727 } | 700 } |
| 728 | 701 |
| 729 bool DrmDevice::SetColorCorrection( | 702 bool DrmDevice::SetColorCorrection( |
| 730 uint32_t crtc_id, | 703 uint32_t crtc_id, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 743 degamma_lut_size = crtc_props->prop_values[i]; | 716 degamma_lut_size = crtc_props->prop_values[i]; |
| 744 } | 717 } |
| 745 if (property && !strcmp(property->name, "GAMMA_LUT_SIZE")) { | 718 if (property && !strcmp(property->name, "GAMMA_LUT_SIZE")) { |
| 746 gamma_lut_size = crtc_props->prop_values[i]; | 719 gamma_lut_size = crtc_props->prop_values[i]; |
| 747 } | 720 } |
| 748 | 721 |
| 749 if (degamma_lut_size && gamma_lut_size) | 722 if (degamma_lut_size && gamma_lut_size) |
| 750 break; | 723 break; |
| 751 } | 724 } |
| 752 | 725 |
| 753 // If we can't find the degamma & gamma lut size, it means the properties | |
| 754 // aren't available. We should then use the legacy gamma ramp ioctl. | |
| 755 if (degamma_lut_size == 0 || gamma_lut_size == 0) { | 726 if (degamma_lut_size == 0 || gamma_lut_size == 0) { |
| 756 return SetGammaRamp(crtc_id, gamma_lut); | 727 LOG(WARNING) << "No available (de)gamma tables."; |
| 728 return false; |
| 757 } | 729 } |
| 758 | 730 |
| 759 ScopedDrmColorLutPtr degamma_blob_data = | 731 ScopedDrmColorLutPtr degamma_blob_data = |
| 760 CreateLutBlob(ResampleLut(degamma_lut, degamma_lut_size)); | 732 CreateLutBlob(ResampleLut(degamma_lut, degamma_lut_size)); |
| 761 ScopedDrmColorLutPtr gamma_blob_data = | 733 ScopedDrmColorLutPtr gamma_blob_data = |
| 762 CreateLutBlob(ResampleLut(gamma_lut, gamma_lut_size)); | 734 CreateLutBlob(ResampleLut(gamma_lut, gamma_lut_size)); |
| 763 ScopedDrmColorCtmPtr ctm_blob_data = CreateCTMBlob(correction_matrix); | 735 ScopedDrmColorCtmPtr ctm_blob_data = CreateCTMBlob(correction_matrix); |
| 764 | 736 |
| 765 for (uint32_t i = 0; i < crtc_props->count_props; ++i) { | 737 for (uint32_t i = 0; i < crtc_props->count_props; ++i) { |
| 766 ScopedDrmPropertyPtr property( | 738 ScopedDrmPropertyPtr property( |
| (...skipping 24 matching lines...) Expand all Loading... |
| 791 reinterpret_cast<unsigned char*>(ctm_blob_data.get()), | 763 reinterpret_cast<unsigned char*>(ctm_blob_data.get()), |
| 792 sizeof(DrmColorCtm))) | 764 sizeof(DrmColorCtm))) |
| 793 return false; | 765 return false; |
| 794 } | 766 } |
| 795 } | 767 } |
| 796 | 768 |
| 797 return true; | 769 return true; |
| 798 } | 770 } |
| 799 | 771 |
| 800 } // namespace ui | 772 } // namespace ui |
| OLD | NEW |